home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / mamesrc / src / mame / usrintrf.c < prev   
Encoding:
C/C++ Source or Header  |  1999-12-03  |  86.9 KB  |  3,678 lines

  1. /*********************************************************************
  2.  
  3.   usrintrf.c
  4.  
  5.   Functions used to handle MAME's crude user interface.
  6.  
  7. *********************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "info.h"
  11. #include "vidhrdw/vector.h"
  12. #include "datafile.h"
  13.  
  14. extern int need_to_clear_bitmap;    /* used to tell updatescreen() to clear the bitmap */
  15. extern int bitmap_dirty;    /* set by osd_clearbitmap() */
  16.  
  17. /* Variables for stat menu */
  18. extern char build_version[];
  19. extern unsigned int dispensed_tickets;
  20. extern unsigned int coins[COIN_COUNTERS];
  21.  
  22. /* MARTINEZ.F 990207 Memory Card */
  23. #ifndef NEOFREE
  24. #ifndef TINY_COMPILE
  25. int         memcard_menu(int);
  26. extern int    mcd_action;
  27. extern int    mcd_number;
  28. extern int    memcard_status;
  29. extern int    memcard_number;
  30. extern int    memcard_manager;
  31. #endif
  32. #endif
  33.  
  34. extern int neogeo_memcard_load(int);
  35. extern void neogeo_memcard_save(void);
  36. extern void neogeo_memcard_eject(void);
  37. extern int neogeo_memcard_create(int);
  38. /* MARTINEZ.F 990207 Memory Card End */
  39.  
  40.  
  41.  
  42. void set_ui_visarea (int xmin, int ymin, int xmax, int ymax)
  43. {
  44.     int temp,w,h;
  45.  
  46.     if (Machine->orientation & ORIENTATION_SWAP_XY)
  47.     {
  48.         w = Machine->drv->screen_height;
  49.         h = Machine->drv->screen_width;
  50.     }
  51.     else
  52.     {
  53.         w = Machine->drv->screen_width;
  54.         h = Machine->drv->screen_height;
  55.     }
  56.     if (Machine->ui_orientation & ORIENTATION_FLIP_X)
  57.     {
  58.         temp = w - xmin - 1;
  59.         xmin = w - xmax - 1;
  60.         xmax = temp;
  61.     }
  62.     if (Machine->ui_orientation & ORIENTATION_FLIP_Y)
  63.     {
  64.         temp = h - ymin - 1;
  65.         ymin = h - ymax - 1;
  66.         ymax = temp;
  67.     }
  68.     if (Machine->ui_orientation & ORIENTATION_SWAP_XY)
  69.     {
  70.         temp = xmin; xmin = ymin; ymin = temp;
  71.         temp = xmax; xmax = ymax; ymax = temp;
  72.     }
  73.  
  74.     Machine->uiwidth = xmax-xmin+1;
  75.     Machine->uiheight = ymax-ymin+1;
  76.     Machine->uixmin = xmin;
  77.     Machine->uiymin = ymin;
  78. }
  79.  
  80.  
  81.  
  82. struct GfxElement *builduifont(void)
  83. {
  84.     static unsigned char fontdata6x8[] =
  85.     {
  86.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  87.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  88.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  89.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  90.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  91.         0x30,0x48,0x84,0xb4,0xb4,0x84,0x48,0x30,0x30,0x48,0x84,0x84,0x84,0x84,0x48,0x30,
  92.         0x00,0xfc,0x84,0x8c,0xd4,0xa4,0xfc,0x00,0x00,0xfc,0x84,0x84,0x84,0x84,0xfc,0x00,
  93.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x68,0x78,0x78,0x30,0x00,0x00,
  94.         0x80,0xc0,0xe0,0xf0,0xe0,0xc0,0x80,0x00,0x04,0x0c,0x1c,0x3c,0x1c,0x0c,0x04,0x00,
  95.         0x20,0x70,0xf8,0x20,0x20,0xf8,0x70,0x20,0x48,0x48,0x48,0x48,0x48,0x00,0x48,0x00,
  96.         0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x30,0x68,0x78,0x78,0x30,0x00,0x00,
  97.         0x70,0xd8,0xe8,0xe8,0xf8,0xf8,0x70,0x00,0x1c,0x7c,0x74,0x44,0x44,0x4c,0xcc,0xc0,
  98.         0x20,0x70,0xf8,0x70,0x70,0x70,0x70,0x00,0x70,0x70,0x70,0x70,0xf8,0x70,0x20,0x00,
  99.         0x00,0x10,0xf8,0xfc,0xf8,0x10,0x00,0x00,0x00,0x20,0x7c,0xfc,0x7c,0x20,0x00,0x00,
  100.         0xb0,0x54,0xb8,0xb8,0x54,0xb0,0x00,0x00,0x00,0x28,0x6c,0xfc,0x6c,0x28,0x00,0x00,
  101.         0x00,0x30,0x30,0x78,0x78,0xfc,0x00,0x00,0xfc,0x78,0x78,0x30,0x30,0x00,0x00,0x00,
  102.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,
  103.         0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xf8,0x50,0xf8,0x50,0x00,0x00,
  104.         0x20,0x70,0xc0,0x70,0x18,0xf0,0x20,0x00,0x40,0xa4,0x48,0x10,0x20,0x48,0x94,0x08,
  105.         0x60,0x90,0xa0,0x40,0xa8,0x90,0x68,0x00,0x10,0x20,0x40,0x00,0x00,0x00,0x00,0x00,
  106.         0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x00,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x00,
  107.         0x20,0xa8,0x70,0xf8,0x70,0xa8,0x20,0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00,
  108.         0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,
  109.         0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,
  110.         0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x00,
  111.         0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x00,0x70,0x88,0x08,0x30,0x08,0x88,0x70,0x00,
  112.         0x10,0x30,0x50,0x90,0xf8,0x10,0x10,0x00,0xf8,0x80,0xf0,0x08,0x08,0x88,0x70,0x00,
  113.         0x70,0x80,0xf0,0x88,0x88,0x88,0x70,0x00,0xf8,0x08,0x08,0x10,0x20,0x20,0x20,0x00,
  114.         0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x70,0x00,
  115.         0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,
  116.         0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,
  117.         0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00,
  118.         0x30,0x48,0x94,0xa4,0xa4,0x94,0x48,0x30,0x70,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,
  119.         0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,
  120.         0xf0,0x88,0x88,0x88,0x88,0x88,0xf0,0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x00,
  121.         0xf8,0x80,0x80,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x80,0x98,0x88,0x88,0x70,0x00,
  122.         0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
  123.         0x08,0x08,0x08,0x08,0x88,0x88,0x70,0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x00,
  124.         0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x00,
  125.         0x88,0xc8,0xa8,0x98,0x88,0x88,0x88,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
  126.         0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x08,
  127.         0xf0,0x88,0x88,0xf0,0x88,0x88,0x88,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,
  128.         0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,
  129.         0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00,0x88,0x88,0x88,0x88,0xa8,0xd8,0x88,0x00,
  130.         0x88,0x50,0x20,0x20,0x20,0x50,0x88,0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x00,
  131.         0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x30,0x20,0x20,0x20,0x20,0x20,0x30,0x00,
  132.         0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x30,0x10,0x10,0x10,0x10,0x10,0x30,0x00,
  133.         0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,
  134.         0x40,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00,
  135.         0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x78,0x00,
  136.         0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00,0x00,0x00,0x70,0x88,0xf8,0x80,0x78,0x00,
  137.         0x18,0x20,0x70,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x70,
  138.         0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x00,
  139.         0x20,0x00,0x20,0x20,0x20,0x20,0x20,0xc0,0x80,0x80,0x90,0xa0,0xe0,0x90,0x88,0x00,
  140.         0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xf0,0xa8,0xa8,0xa8,0xa8,0x00,
  141.         0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00,
  142.         0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x08,
  143.         0x00,0x00,0xb0,0xc8,0x80,0x80,0x80,0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xf0,0x00,
  144.         0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00,
  145.         0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00,0x00,0x00,0xa8,0xa8,0xa8,0xa8,0x50,0x00,
  146.         0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70,
  147.         0x00,0x00,0xf8,0x10,0x20,0x40,0xf8,0x00,0x08,0x10,0x10,0x20,0x10,0x10,0x08,0x00,
  148.         0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00,
  149.         0x00,0x68,0xb0,0x00,0x00,0x00,0x00,0x00,0x20,0x50,0x20,0x50,0xa8,0x50,0x00,0x00,
  150.     };
  151. #if 0       /* HJB 990215 unused!? */
  152.     static unsigned char fontdata8x8[] =
  153.     {
  154.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  155.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  156.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  157.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  158.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  159.         0x3C,0x42,0x99,0xBD,0xBD,0x99,0x42,0x3C,0x3C,0x42,0x81,0x81,0x81,0x81,0x42,0x3C,
  160.         0xFE,0x82,0x8A,0xD2,0xA2,0x82,0xFE,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,
  161.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
  162.         0x80,0xC0,0xF0,0xFC,0xF0,0xC0,0x80,0x00,0x01,0x03,0x0F,0x3F,0x0F,0x03,0x01,0x00,
  163.         0x18,0x3C,0x7E,0x18,0x7E,0x3C,0x18,0x00,0xEE,0xEE,0xEE,0xCC,0x00,0xCC,0xCC,0x00,
  164.         0x00,0x00,0x30,0x68,0x78,0x30,0x00,0x00,0x00,0x38,0x64,0x74,0x7C,0x38,0x00,0x00,
  165.         0x3C,0x66,0x7A,0x7A,0x7E,0x7E,0x3C,0x00,0x0E,0x3E,0x3A,0x22,0x26,0x6E,0xE4,0x40,
  166.         0x18,0x3C,0x7E,0x3C,0x3C,0x3C,0x3C,0x00,0x3C,0x3C,0x3C,0x3C,0x7E,0x3C,0x18,0x00,
  167.         0x08,0x7C,0x7E,0x7E,0x7C,0x08,0x00,0x00,0x10,0x3E,0x7E,0x7E,0x3E,0x10,0x00,0x00,
  168.         0x58,0x2A,0xDC,0xC8,0xDC,0x2A,0x58,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00,
  169.         0x00,0x10,0x10,0x38,0x38,0x7C,0xFE,0x00,0xFE,0x7C,0x38,0x38,0x10,0x10,0x00,0x00,
  170.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x18,0x00,0x18,0x18,0x00,
  171.         0x6C,0x6C,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,
  172.         0x10,0x38,0x60,0x38,0x0C,0x78,0x10,0x00,0x40,0xA4,0x48,0x10,0x24,0x4A,0x04,0x00,
  173.         0x18,0x34,0x18,0x3A,0x6C,0x66,0x3A,0x00,0x18,0x18,0x20,0x00,0x00,0x00,0x00,0x00,
  174.         0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x00,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x00,
  175.         0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
  176.         0x00,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,
  177.         0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x00,0x00,
  178.         0x38,0x4C,0xC6,0xC6,0xC6,0x64,0x38,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00,
  179.         0x7C,0xC6,0x0E,0x3C,0x78,0xE0,0xFE,0x00,0x7E,0x0C,0x18,0x3C,0x06,0xC6,0x7C,0x00,
  180.         0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x00,0xFC,0xC0,0xFC,0x06,0x06,0xC6,0x7C,0x00,
  181.         0x3C,0x60,0xC0,0xFC,0xC6,0xC6,0x7C,0x00,0xFE,0xC6,0x0C,0x18,0x30,0x30,0x30,0x00,
  182.         0x78,0xC4,0xE4,0x78,0x86,0x86,0x7C,0x00,0x7C,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
  183.         0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30,
  184.         0x1C,0x38,0x70,0xE0,0x70,0x38,0x1C,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,
  185.         0x70,0x38,0x1C,0x0E,0x1C,0x38,0x70,0x00,0x7C,0xC6,0xC6,0x1C,0x18,0x00,0x18,0x00,
  186.         0x3C,0x42,0x99,0xA1,0xA5,0x99,0x42,0x3C,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00,
  187.         0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,
  188.         0xF8,0xCC,0xC6,0xC6,0xC6,0xCC,0xF8,0x00,0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xFE,0x00,
  189.         0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0x00,0x3E,0x60,0xC0,0xCE,0xC6,0x66,0x3E,0x00,
  190.         0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,
  191.         0x06,0x06,0x06,0x06,0xC6,0xC6,0x7C,0x00,0xC6,0xCC,0xD8,0xF0,0xF8,0xDC,0xCE,0x00,
  192.         0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,
  193.         0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
  194.         0xFC,0xC6,0xC6,0xC6,0xFC,0xC0,0xC0,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x7A,0x00,
  195.         0xFC,0xC6,0xC6,0xCE,0xF8,0xDC,0xCE,0x00,0x78,0xCC,0xC0,0x7C,0x06,0xC6,0x7C,0x00,
  196.         0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,
  197.         0xC6,0xC6,0xC6,0xEE,0x7C,0x38,0x10,0x00,0xC6,0xC6,0xD6,0xFE,0xFE,0xEE,0xC6,0x00,
  198.         0xC6,0xEE,0x3C,0x38,0x7C,0xEE,0xC6,0x00,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00,
  199.         0xFE,0x0E,0x1C,0x38,0x70,0xE0,0xFE,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,
  200.         0x60,0x60,0x30,0x18,0x0C,0x06,0x06,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,
  201.         0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
  202.         0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3C,0x00,
  203.         0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x00,
  204.         0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x3C,0x00,
  205.         0x1C,0x30,0x78,0x30,0x30,0x30,0x30,0x00,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x3C,
  206.         0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x00,
  207.         0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x38,0x60,0x60,0x66,0x6C,0x78,0x6C,0x66,0x00,
  208.         0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0xEC,0xFE,0xFE,0xFE,0xD6,0xC6,0x00,
  209.         0x00,0x7C,0x76,0x66,0x66,0x66,0x66,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,
  210.         0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x00,0x3E,0x66,0x66,0x66,0x3E,0x06,0x06,
  211.         0x00,0x7E,0x70,0x60,0x60,0x60,0x60,0x00,0x00,0x3C,0x60,0x3C,0x06,0x66,0x3C,0x00,
  212.         0x30,0x78,0x30,0x30,0x30,0x30,0x1C,0x00,0x00,0x66,0x66,0x66,0x66,0x6E,0x3E,0x00,
  213.         0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x7C,0x6C,0x00,
  214.         0x00,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C,
  215.         0x00,0x7E,0x0C,0x18,0x30,0x60,0x7E,0x00,0x0E,0x18,0x0C,0x38,0x0C,0x18,0x0E,0x00,
  216.         0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x70,0x18,0x30,0x1C,0x30,0x18,0x70,0x00,
  217.         0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x10,0x28,0x10,0x54,0xAA,0x44,0x00,0x00,
  218.     };
  219. #endif
  220.     static struct GfxLayout fontlayout6x8 =
  221.     {
  222.         6,8,    /* 6*8 characters */
  223.         128,    /* 128 characters */
  224.         1,    /* 1 bit per pixel */
  225.         { 0 },
  226.         { 0, 1, 2, 3, 4, 5, 6, 7 },    /* straightforward layout */
  227.         { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
  228.         8*8    /* every char takes 8 consecutive bytes */
  229.     };
  230.     static struct GfxLayout fontlayout12x8 =
  231.     {
  232.         12,8,    /* 12*8 characters */
  233.         128,    /* 128 characters */
  234.         1,    /* 1 bit per pixel */
  235.         { 0 },
  236.         { 0,0, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 },    /* straightforward layout */
  237.         { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
  238.         8*8    /* every char takes 8 consecutive bytes */
  239.     };
  240.     static struct GfxLayout fontlayout12x16 =
  241.     {
  242.         12,16,    /* 6*8 characters */
  243.         128,    /* 128 characters */
  244.         1,    /* 1 bit per pixel */
  245.         { 0 },
  246.         { 0,0, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 },    /* straightforward layout */
  247.         { 0*8,0*8, 1*8,1*8, 2*8,2*8, 3*8,3*8, 4*8,4*8, 5*8,5*8, 6*8,6*8, 7*8,7*8 },
  248.         8*8    /* every char takes 8 consecutive bytes */
  249.     };
  250. #if 0    /* HJB 990215 unused!? */
  251.     static struct GfxLayout fontlayout8x8 =
  252.     {
  253.         8,8,    /* 8*8 characters */
  254.         128,    /* 128 characters */
  255.         1,    /* 1 bit per pixel */
  256.         { 0 },
  257.         { 0, 1, 2, 3, 4, 5, 6, 7 },    /* straightforward layout */
  258.         { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
  259.         8*8    /* every char takes 8 consecutive bytes */
  260.     };
  261. #endif
  262.     struct GfxElement *font;
  263.     static unsigned short colortable[2*2];    /* ASG 980209 */
  264.     int trueorientation;
  265.  
  266.  
  267.     /* hack: force the display into standard orientation to avoid */
  268.     /* creating a rotated font */
  269.     trueorientation = Machine->orientation;
  270.     Machine->orientation = Machine->ui_orientation;
  271.  
  272.     if ((Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_MASK)
  273.             == VIDEO_PIXEL_ASPECT_RATIO_1_2)
  274.     {
  275.         font = decodegfx(fontdata6x8,&fontlayout12x8);
  276.         Machine->uifontwidth = 12;
  277.         Machine->uifontheight = 8;
  278.     }
  279.     else if (Machine->uiwidth >= 420 && Machine->uiheight >= 420)
  280.     {
  281.         font = decodegfx(fontdata6x8,&fontlayout12x16);
  282.         Machine->uifontwidth = 12;
  283.         Machine->uifontheight = 16;
  284.     }
  285.     else
  286.     {
  287.         font = decodegfx(fontdata6x8,&fontlayout6x8);
  288.         Machine->uifontwidth = 6;
  289.         Machine->uifontheight = 8;
  290.     }
  291.  
  292.     if (font)
  293.     {
  294.         /* colortable will be set at run time */
  295.         memset(colortable,0,sizeof(colortable));
  296.         font->colortable = colortable;
  297.         font->total_colors = 2;
  298.     }
  299.  
  300.     Machine->orientation = trueorientation;
  301.  
  302.     return font;
  303. }
  304.  
  305.  
  306.  
  307. /***************************************************************************
  308.  
  309.   Display text on the screen. If erase is 0, it superimposes the text on
  310.   the last frame displayed.
  311.  
  312. ***************************************************************************/
  313.  
  314. void displaytext(const struct DisplayText *dt,int erase,int update_screen)
  315. {
  316.     int trueorientation;
  317.  
  318.     if (erase)
  319.         osd_clearbitmap(Machine->scrbitmap);
  320.  
  321.  
  322.     /* hack: force the display into standard orientation to avoid */
  323.     /* rotating the user interface */
  324.     trueorientation = Machine->orientation;
  325.     Machine->orientation = Machine->ui_orientation;
  326.  
  327.     osd_mark_dirty (0,0,Machine->uiwidth-1,Machine->uiheight-1,1);    /* ASG 971011 */
  328.  
  329.     while (dt->text)
  330.     {
  331.         int x,y;
  332.         const char *c;
  333.  
  334.         x = dt->x;
  335.         y = dt->y;
  336.         c = dt->text;
  337.  
  338.         while (*c)
  339.         {
  340.             int wrapped;
  341.  
  342.             wrapped = 0;
  343.  
  344.             if (*c == '\n')
  345.             {
  346.                 x = dt->x;
  347.                 y += Machine->uifontheight + 1;
  348.                 wrapped = 1;
  349.             }
  350.             else if (*c == ' ')
  351.             {
  352.                 /* don't try to word wrap at the beginning of a line (this would cause */
  353.                 /* an endless loop if a word is longer than a line) */
  354.                 if (x != dt->x)
  355.                 {
  356.                     int nextlen=0;
  357.                     const char *nc;
  358.  
  359.  
  360.                     nc = c+1;
  361.                     while (*nc && *nc != ' ' && *nc != '\n')
  362.                     {
  363.                         nextlen += Machine->uifontwidth;
  364.                         nc++;
  365.                     }
  366.  
  367.                     /* word wrap */
  368.                     if (x + Machine->uifontwidth + nextlen > Machine->uiwidth)
  369.                     {
  370.                         x = dt->x;
  371.                         y += Machine->uifontheight + 1;
  372.                         wrapped = 1;
  373.                     }
  374.                 }
  375.             }
  376.  
  377.             if (!wrapped)
  378.             {
  379.                 drawgfx(Machine->scrbitmap,Machine->uifont,*c,dt->color,0,0,x+Machine->uixmin,y+Machine->uiymin,0,TRANSPARENCY_NONE,0);
  380.                 x += Machine->uifontwidth;
  381.             }
  382.  
  383.             c++;
  384.         }
  385.  
  386.         dt++;
  387.     }
  388.  
  389.     Machine->orientation = trueorientation;
  390.  
  391.     if (update_screen) osd_update_video_and_audio();
  392. }
  393.  
  394. /* Writes messages on the screen. */
  395. void ui_text(char *buf,int x,int y)
  396. {
  397.     int trueorientation,l,i;
  398.  
  399.  
  400.     /* hack: force the display into standard orientation to avoid */
  401.     /* rotating the text */
  402.     trueorientation = Machine->orientation;
  403.     Machine->orientation = Machine->ui_orientation;
  404.  
  405.     l = strlen(buf);
  406.     for (i = 0;i < l;i++)
  407.         drawgfx(Machine->scrbitmap,Machine->uifont,buf[i],DT_COLOR_WHITE,0,0,
  408.                 x + i*Machine->uifontwidth + Machine->uixmin,
  409.                 y + Machine->uiymin, 0,TRANSPARENCY_NONE,0);
  410.  
  411.     Machine->orientation = trueorientation;
  412. }
  413.  
  414.  
  415. INLINE void drawpixel(int x, int y, unsigned short color)
  416. {
  417.     int temp;
  418.  
  419.     if (Machine->ui_orientation & ORIENTATION_SWAP_XY)
  420.     {
  421.         temp = x; x = y; y = temp;
  422.     }
  423.     if (Machine->ui_orientation & ORIENTATION_FLIP_X)
  424.         x = Machine->scrbitmap->width - x - 1;
  425.     if (Machine->ui_orientation & ORIENTATION_FLIP_Y)
  426.         y = Machine->scrbitmap->height - y - 1;
  427.  
  428.     if (Machine->scrbitmap->depth == 16)
  429.         *(unsigned short *)&Machine->scrbitmap->line[y][x*2] = color;
  430.     else
  431.         Machine->scrbitmap->line[y][x] = color;
  432.  
  433.     osd_mark_dirty(x,y,x,y,1);
  434. }
  435.  
  436. INLINE void drawhline_norotate(int x, int w, int y, unsigned short color)
  437. {
  438.     if (Machine->scrbitmap->depth == 16)
  439.     {
  440.         int i;
  441.         for (i = x; i < x+w; i++)
  442.             *(unsigned short *)&Machine->scrbitmap->line[y][i*2] = color;
  443.     }
  444.     else
  445.         memset(&Machine->scrbitmap->line[y][x], color, w);
  446.  
  447.     osd_mark_dirty(x,y,x+w-1,y,1);
  448. }
  449.  
  450. INLINE void drawvline_norotate(int x, int y, int h, unsigned short color)
  451. {
  452.     int i;
  453.  
  454.     if (Machine->scrbitmap->depth == 16)
  455.     {
  456.         for (i = y; i < y+h; i++)
  457.             *(unsigned short *)&Machine->scrbitmap->line[i][x*2] = color;
  458.     }
  459.     else
  460.     {
  461.         for (i = y; i < y+h; i++)
  462.             Machine->scrbitmap->line[i][x] = color;
  463.     }
  464.  
  465.     osd_mark_dirty(x,y,x,y+h-1,1);
  466. }
  467.  
  468. INLINE void drawhline(int x, int w, int y, unsigned short color)
  469. {
  470.     if (Machine->ui_orientation & ORIENTATION_SWAP_XY)
  471.     {
  472.         if (Machine->ui_orientation & ORIENTATION_FLIP_X)
  473.             y = Machine->scrbitmap->width - y - 1;
  474.         if (Machine->ui_orientation & ORIENTATION_FLIP_Y)
  475.             x = Machine->scrbitmap->height - x - w;
  476.  
  477.         drawvline_norotate(y,x,w,color);
  478.     }
  479.     else
  480.     {
  481.         if (Machine->ui_orientation & ORIENTATION_FLIP_X)
  482.             x = Machine->scrbitmap->width - x - w;
  483.         if (Machine->ui_orientation & ORIENTATION_FLIP_Y)
  484.             y = Machine->scrbitmap->height - y - 1;
  485.  
  486.         drawhline_norotate(x,w,y,color);
  487.     }
  488. }
  489.  
  490. INLINE void drawvline(int x, int y, int h, unsigned short color)
  491. {
  492.     if (Machine->ui_orientation & ORIENTATION_SWAP_XY)
  493.     {
  494.         if (Machine->ui_orientation & ORIENTATION_FLIP_X)
  495.             y = Machine->scrbitmap->width - y - h;
  496.         if (Machine->ui_orientation & ORIENTATION_FLIP_Y)
  497.             x = Machine->scrbitmap->height - x - 1;
  498.  
  499.         drawhline_norotate(y,h,x,color);
  500.     }
  501.     else
  502.     {
  503.         if (Machine->ui_orientation & ORIENTATION_FLIP_X)
  504.             x = Machine->scrbitmap->width - x - 1;
  505.         if (Machine->ui_orientation & ORIENTATION_FLIP_Y)
  506.             y = Machine->scrbitmap->height - y - h;
  507.  
  508.         drawvline_norotate(x,y,h,color);
  509.     }
  510. }
  511.  
  512.  
  513. static void drawbox(int leftx,int topy,int width,int height)
  514. {
  515.     int y;
  516.     unsigned short black,white;
  517.  
  518.  
  519.     if (leftx < 0) leftx = 0;
  520.     if (topy < 0) topy = 0;
  521.     if (width > Machine->uiwidth) width = Machine->uiwidth;
  522.     if (height > Machine->uiheight) height = Machine->uiheight;
  523.  
  524.     leftx += Machine->uixmin;
  525.     topy += Machine->uiymin;
  526.  
  527.     black = Machine->uifont->colortable[0];
  528.     white = Machine->uifont->colortable[1];
  529.  
  530.     drawhline(leftx,width,topy,         white);
  531.     drawhline(leftx,width,topy+height-1,white);
  532.     drawvline(leftx,        topy,height,white);
  533.     drawvline(leftx+width-1,topy,height,white);
  534.     for (y = topy+1;y < topy+height-1;y++)
  535.         drawhline(leftx+1,width-2,y,black);
  536. }
  537.  
  538.  
  539. static void drawbar(int leftx,int topy,int width,int height,int percentage)
  540. {
  541.     int y;
  542.     unsigned short black,white;
  543.  
  544.  
  545.     if (leftx < 0) leftx = 0;
  546.     if (topy < 0) topy = 0;
  547.     if (width > Machine->uiwidth) width = Machine->uiwidth;
  548.     if (height > Machine->uiheight) height = Machine->uiheight;
  549.  
  550.     leftx += Machine->uixmin;
  551.     topy += Machine->uiymin;
  552.  
  553.     black = Machine->uifont->colortable[0];
  554.     white = Machine->uifont->colortable[1];
  555.  
  556.     for (y = topy;y < topy + height/8;y++)
  557.     {
  558.         drawpixel(leftx,            y, white);
  559.         drawpixel(leftx+1,            y, white);
  560.         drawpixel(leftx+width/2-1,    y, white);
  561.         drawpixel(leftx+width/2,    y, white);
  562.         drawpixel(leftx+width-2,    y, white);
  563.         drawpixel(leftx+width-1,    y, white);
  564.     }
  565.     for (y = topy+height/8;y < topy+height-height/8;y++)
  566.         drawhline(leftx,width*percentage/100,y,white);
  567.     for (y = topy+height-height/8;y < topy + height;y++)
  568.     {
  569.         drawpixel(leftx,            y, white);
  570.         drawpixel(leftx+1,            y, white);
  571.         drawpixel(leftx+width/2-1,    y, white);
  572.         drawpixel(leftx+width/2,    y, white);
  573.         drawpixel(leftx+width-2,    y, white);
  574.         drawpixel(leftx+width-1,    y, white);
  575.     }
  576. }
  577.  
  578.  
  579. void displaymenu(const char **items,const char **subitems,char *flag,int selected,int arrowize_subitem)
  580. {
  581.     struct DisplayText dt[256];
  582.     int curr_dt;
  583.     char lefthilight[2] = "\x1a";
  584.     char righthilight[2] = "\x1b";
  585.     char uparrow[2] = "\x18";
  586.     char downarrow[2] = "\x19";
  587.     char leftarrow[2] = "\x11";
  588.     char rightarrow[2] = "\x10";
  589.     int i,count,len,maxlen;
  590.     int leftoffs,topoffs,visible,topitem;
  591.  
  592.  
  593.     i = 0;
  594.     maxlen = 0;
  595.     while (items[i])
  596.     {
  597.         len = strlen(items[i]);
  598.         if (subitems && subitems[i])
  599.         {
  600.             len += 1 + strlen(subitems[i]);
  601.         }
  602.         if (len > maxlen) maxlen = len;
  603.         i++;
  604.     }
  605.     count = i;
  606.  
  607.     maxlen += 3;
  608.     if (maxlen * Machine->uifontwidth > Machine->uiwidth)
  609.         maxlen = Machine->uiwidth / Machine->uifontwidth;
  610.  
  611.     visible = Machine->uiheight / (3 * Machine->uifontheight / 2) - 1;
  612.     topitem = 0;
  613.     if (visible > count) visible = count;
  614.     else
  615.     {
  616.         topitem = selected - visible / 2;
  617.         if (topitem < 0) topitem = 0;
  618.         if (topitem > count - visible) topitem = count - visible;
  619.     }
  620.  
  621.     leftoffs = (Machine->uiwidth - maxlen * Machine->uifontwidth) / 2;
  622.     topoffs = (Machine->uiheight - (3 * visible + 1) * Machine->uifontheight / 2) / 2;
  623.  
  624.     /* black background */
  625.     drawbox(leftoffs,topoffs,maxlen * Machine->uifontwidth,(3 * visible + 1) * Machine->uifontheight / 2);
  626.  
  627.     curr_dt = 0;
  628.     for (i = 0;i < visible;i++)
  629.     {
  630.         int item = i + topitem;
  631.  
  632.         if (i == 0 && item > 0)
  633.         {
  634.             dt[curr_dt].text = uparrow;
  635.             dt[curr_dt].color = DT_COLOR_WHITE;
  636.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(uparrow)) / 2;
  637.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  638.             curr_dt++;
  639.         }
  640.         else if (i == visible - 1 && item < count - 1)
  641.         {
  642.             dt[curr_dt].text = downarrow;
  643.             dt[curr_dt].color = DT_COLOR_WHITE;
  644.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(downarrow)) / 2;
  645.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  646.             curr_dt++;
  647.         }
  648.         else
  649.         {
  650.             if (subitems && subitems[item])
  651.             {
  652.                 dt[curr_dt].text = items[item];
  653.                 dt[curr_dt].color = DT_COLOR_WHITE;
  654.                 dt[curr_dt].x = leftoffs + 3*Machine->uifontwidth/2;
  655.                 dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  656.                 curr_dt++;
  657.                 dt[curr_dt].text = subitems[item];
  658.                 /* If this item is flagged, draw it in inverse print */
  659.                 if (flag && flag[item])
  660.                     dt[curr_dt].color = DT_COLOR_YELLOW;
  661.                 else
  662.                     dt[curr_dt].color = DT_COLOR_WHITE;
  663.                 dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-1 - strlen(dt[curr_dt].text)) - Machine->uifontwidth/2;
  664.                 dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  665.                 curr_dt++;
  666.             }
  667.             else
  668.             {
  669.                 dt[curr_dt].text = items[item];
  670.                 dt[curr_dt].color = DT_COLOR_WHITE;
  671.                 dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(items[item])) / 2;
  672.                 dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  673.                 curr_dt++;
  674.             }
  675.         }
  676.     }
  677.  
  678.     i = selected - topitem;
  679.     if (subitems && subitems[selected] && arrowize_subitem)
  680.     {
  681.         if (arrowize_subitem & 1)
  682.         {
  683.             dt[curr_dt].text = leftarrow;
  684.             dt[curr_dt].color = DT_COLOR_WHITE;
  685.             dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-2 - strlen(subitems[selected])) - Machine->uifontwidth/2 - 1;
  686.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  687.             curr_dt++;
  688.         }
  689.         if (arrowize_subitem & 2)
  690.         {
  691.             dt[curr_dt].text = rightarrow;
  692.             dt[curr_dt].color = DT_COLOR_WHITE;
  693.             dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-1) - Machine->uifontwidth/2;
  694.             dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  695.             curr_dt++;
  696.         }
  697.     }
  698.     else
  699.     {
  700.         dt[curr_dt].text = righthilight;
  701.         dt[curr_dt].color = DT_COLOR_WHITE;
  702.         dt[curr_dt].x = leftoffs + Machine->uifontwidth * (maxlen-1) - Machine->uifontwidth/2;
  703.         dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  704.         curr_dt++;
  705.     }
  706.     dt[curr_dt].text = lefthilight;
  707.     dt[curr_dt].color = DT_COLOR_WHITE;
  708.     dt[curr_dt].x = leftoffs + Machine->uifontwidth/2;
  709.     dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  710.     curr_dt++;
  711.  
  712.     dt[curr_dt].text = 0;    /* terminate array */
  713.  
  714.     displaytext(dt,0,0);
  715. }
  716.  
  717.  
  718. static void displaymessagewindow(const char *text)
  719. {
  720.     struct DisplayText dt[256];
  721.     int curr_dt;
  722.     char *c,*c2;
  723.     int i,len,maxlen,lines;
  724.     char textcopy[2048];
  725.     int leftoffs,topoffs;
  726.     int    maxcols,maxrows;
  727.  
  728.     maxcols = (Machine->uiwidth / Machine->uifontwidth) - 1;
  729.     maxrows = (2 * Machine->uiheight - Machine->uifontheight) / (3 * Machine->uifontheight);
  730.  
  731.     /* copy text, calculate max len, count lines, wrap long lines and crop height to fit */
  732.     maxlen = 0;
  733.     lines = 0;
  734.     c = (char *)text;
  735.     c2 = textcopy;
  736.     while (*c)
  737.     {
  738.         len = 0;
  739.         while (*c && *c != '\n')
  740.         {
  741.             *c2++ = *c++;
  742.             len++;
  743.             if (len == maxcols && *c != '\n')
  744.             {
  745.                 /* attempt word wrap */
  746.                 char *csave = c, *c2save = c2;
  747.                 int lensave = len;
  748.  
  749.                 /* back up to last space or beginning of line */
  750.                 while (*c != ' ' && *c != '\n' && c > text)
  751.                     --c, --c2, --len;
  752.  
  753.                 /* if no space was found, hard wrap instead */
  754.                 if (*c != ' ')
  755.                     c = csave, c2 = c2save, len = lensave;
  756.                 else
  757.                     c++;
  758.  
  759.                 *c2++ = '\n'; /* insert wrap */
  760.                 break;
  761.             }
  762.         }
  763.  
  764.         if (*c == '\n')
  765.             *c2++ = *c++;
  766.  
  767.         if (len > maxlen) maxlen = len;
  768.  
  769.         lines++;
  770.         if (lines == maxrows)
  771.             break;
  772.     }
  773.     *c2 = '\0';
  774.  
  775.     maxlen += 1;
  776.  
  777.     leftoffs = (Machine->uiwidth - Machine->uifontwidth * maxlen) / 2;
  778.     if (leftoffs < 0) leftoffs = 0;
  779.     topoffs = (Machine->uiheight - (3 * lines + 1) * Machine->uifontheight / 2) / 2;
  780.  
  781.     /* black background */
  782.     drawbox(leftoffs,topoffs,maxlen * Machine->uifontwidth,(3 * lines + 1) * Machine->uifontheight / 2);
  783.  
  784.     curr_dt = 0;
  785.     c = textcopy;
  786.     i = 0;
  787.     while (*c)
  788.     {
  789.         c2 = c;
  790.         while (*c && *c != '\n')
  791.             c++;
  792.  
  793.         if (*c == '\n')
  794.         {
  795.             *c = '\0';
  796.             c++;
  797.         }
  798.  
  799.         if (*c2 == '\t')    /* center text */
  800.         {
  801.             c2++;
  802.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * (c - c2)) / 2;
  803.         }
  804.         else
  805.             dt[curr_dt].x = leftoffs + Machine->uifontwidth/2;
  806.  
  807.         dt[curr_dt].text = c2;
  808.         dt[curr_dt].color = DT_COLOR_WHITE;
  809.         dt[curr_dt].y = topoffs + (3*i+1)*Machine->uifontheight/2;
  810.         curr_dt++;
  811.  
  812.         i++;
  813.     }
  814.  
  815.     dt[curr_dt].text = 0;    /* terminate array */
  816.  
  817.     displaytext(dt,0,0);
  818. }
  819.  
  820.  
  821.  
  822. #ifndef NEOFREE
  823. #ifndef TINY_COMPILE
  824. extern int no_of_tiles;
  825. void NeoMVSDrawGfx(unsigned char **line,const struct GfxElement *gfx,
  826.         unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
  827.         int zx,int zy,const struct rectangle *clip);
  828. void NeoMVSDrawGfx16(unsigned char **line,const struct GfxElement *gfx,
  829.         unsigned int code,unsigned int color,int flipx,int flipy,int sx,int sy,
  830.         int zx,int zy,const struct rectangle *clip);
  831. extern struct GameDriver neogeo_bios;
  832. #endif
  833. #endif
  834.  
  835. static void showcharset(void)
  836. {
  837.     int i;
  838.     struct DisplayText dt[2];
  839.     char buf[80];
  840.     int bank,color,firstdrawn;
  841.     int trueorientation;
  842.     int changed;
  843.     int game_is_neogeo=0;
  844.  
  845.  
  846.     if ((Machine->drv->gfxdecodeinfo == 0) ||
  847.             (Machine->drv->gfxdecodeinfo[0].memory_region == -1))
  848.         return;    /* no gfx sets, return */
  849.  
  850. #ifndef NEOFREE
  851. #ifndef TINY_COMPILE
  852.     if (Machine->gamedrv->clone_of == &neogeo_bios ||
  853.             (Machine->gamedrv->clone_of &&
  854.                 Machine->gamedrv->clone_of->clone_of == &neogeo_bios))
  855.         game_is_neogeo=1;
  856. #endif
  857. #endif
  858.  
  859.     /* hack: force the display into standard orientation to avoid */
  860.     /* rotating the user interface */
  861.     trueorientation = Machine->orientation;
  862.     Machine->orientation = Machine->ui_orientation;
  863.  
  864.  
  865.     bank = 0;
  866.     color = 0;
  867.     firstdrawn = 0;
  868.  
  869.     changed = 1;
  870.  
  871.     do
  872.     {
  873.         int cpx,cpy,skip_chars;
  874.  
  875.         cpx = Machine->uiwidth / Machine->gfx[bank]->width;
  876.         cpy = (Machine->uiheight - Machine->uifontheight) / Machine->gfx[bank]->height;
  877.         skip_chars = cpx * cpy;
  878.  
  879.         if (changed)
  880.         {
  881.             int lastdrawn=0;
  882.  
  883.             osd_clearbitmap(Machine->scrbitmap);
  884.  
  885.             /* validity chack after char bank change */
  886.             if (firstdrawn >= Machine->gfx[bank]->total_elements)
  887.             {
  888.                 firstdrawn = Machine->gfx[bank]->total_elements - skip_chars;
  889.                 if (firstdrawn < 0) firstdrawn = 0;
  890.             }
  891.  
  892.             if(bank!=2 || !game_is_neogeo)
  893.             {
  894.                 for (i = 0; i+firstdrawn < Machine->gfx[bank]->total_elements && i<cpx*cpy; i++)
  895.                 {
  896.                     drawgfx(Machine->scrbitmap,Machine->gfx[bank],
  897.                         i+firstdrawn,color,  /*sprite num, color*/
  898.                         0,0,
  899.                         (i % cpx) * Machine->gfx[bank]->width + Machine->uixmin,
  900.                         Machine->uifontheight + (i / cpx) * Machine->gfx[bank]->height + Machine->uiymin,
  901.                         0,TRANSPARENCY_NONE,0);
  902.  
  903.                     lastdrawn = i+firstdrawn;
  904.                 }
  905.             }
  906. #ifndef NEOFREE
  907. #ifndef TINY_COMPILE
  908.             else    /* neogeo sprite tiles */
  909.             {
  910.                 struct rectangle clip;
  911.  
  912.                 clip.min_x = Machine->uixmin;
  913.                 clip.max_x = Machine->uixmin + Machine->uiwidth - 1;
  914.                 clip.min_y = Machine->uiymin;
  915.                 clip.max_y = Machine->uiymin + Machine->uiheight - 1;
  916.  
  917.                 for (i = 0; i+firstdrawn < no_of_tiles && i<cpx*cpy; i++)
  918.                 {
  919.                     if (Machine->scrbitmap->depth == 16)
  920.                         NeoMVSDrawGfx16(Machine->scrbitmap->line,Machine->gfx[bank],
  921.                             i+firstdrawn,color,  /*sprite num, color*/
  922.                             0,0,
  923.                             (i % cpx) * Machine->gfx[bank]->width + Machine->uixmin,
  924.                             Machine->uifontheight+1 + (i / cpx) * Machine->gfx[bank]->height + Machine->uiymin,
  925.                             16,16,&clip);
  926.                     else
  927.                         NeoMVSDrawGfx(Machine->scrbitmap->line,Machine->gfx[bank],
  928.                             i+firstdrawn,color,  /*sprite num, color*/
  929.                             0,0,
  930.                             (i % cpx) * Machine->gfx[bank]->width + Machine->uixmin,
  931.                             Machine->uifontheight+1 + (i / cpx) * Machine->gfx[bank]->height + Machine->uiymin,
  932.                             16,16,&clip);
  933.  
  934.                     lastdrawn = i+firstdrawn;
  935.                 }
  936.             }
  937. #endif
  938. #endif
  939.  
  940.             sprintf(buf,"GFXSET %d COLOR %d CODE %x-%x",bank,color,firstdrawn,lastdrawn);
  941.             dt[0].text = buf;
  942.             dt[0].color = DT_COLOR_RED;
  943.             dt[0].x = 0;
  944.             dt[0].y = 0;
  945.             dt[1].text = 0;
  946.             displaytext(dt,0,0);
  947.  
  948.             changed = 0;
  949.         }
  950.  
  951.         /* Necessary to keep the video from getting stuck if a frame happens to be skipped in here */
  952. /* I beg to differ - the OS dependant code must not assume that */
  953. /* osd_skip_this_frame() is called before osd_update_video_and_audio() - NS */
  954. //        osd_skip_this_frame();
  955.         osd_update_video_and_audio();
  956.  
  957.         if (osd_key_pressed(OSD_KEY_LCONTROL) || osd_key_pressed(OSD_KEY_RCONTROL))
  958.         {
  959.             skip_chars = cpx;
  960.         }
  961.         if (osd_key_pressed(OSD_KEY_LSHIFT) || osd_key_pressed(OSD_KEY_RSHIFT))
  962.         {
  963.             skip_chars = 1;
  964.         }
  965.  
  966.  
  967.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_RIGHT,8))
  968.         {
  969.             if (bank+1 < MAX_GFX_ELEMENTS && Machine->gfx[bank + 1])
  970.             {
  971.                 bank++;
  972. //                firstdrawn = 0;
  973.                 changed = 1;
  974.             }
  975.         }
  976.  
  977.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_LEFT,8))
  978.         {
  979.             if (bank > 0)
  980.             {
  981.                 bank--;
  982. //                firstdrawn = 0;
  983.                 changed = 1;
  984.             }
  985.         }
  986.  
  987.         if (osd_key_pressed_memory_repeat(OSD_KEY_PGDN,4))
  988.         {
  989.             if (firstdrawn + skip_chars < Machine->gfx[bank]->total_elements)
  990.             {
  991.                 firstdrawn += skip_chars;
  992.                 changed = 1;
  993.             }
  994.         }
  995.  
  996.         if (osd_key_pressed_memory_repeat(OSD_KEY_PGUP,4))
  997.         {
  998.             firstdrawn -= skip_chars;
  999.             if (firstdrawn < 0) firstdrawn = 0;
  1000.             changed = 1;
  1001.         }
  1002.  
  1003.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,6))
  1004.         {
  1005.             if (color < Machine->gfx[bank]->total_colors - 1)
  1006.             {
  1007.                 color++;
  1008.                 changed = 1;
  1009.             }
  1010.         }
  1011.  
  1012.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,6))
  1013.         {
  1014.             if (color > 0)
  1015.             {
  1016.                 color--;
  1017.                 changed = 1;
  1018.             }
  1019.         }
  1020.  
  1021.         if (osd_key_pressed_memory(OSD_KEY_SNAPSHOT))
  1022.         {
  1023.             osd_save_snapshot();
  1024.         }
  1025.     } while (!osd_key_pressed_memory(OSD_KEY_SHOW_GFX) &&
  1026.             !osd_key_pressed_memory(OSD_KEY_CANCEL) &&
  1027.             !osd_key_pressed_memory(OSD_KEY_FAST_EXIT));
  1028.  
  1029.     /* clear the screen before returning */
  1030.     osd_clearbitmap(Machine->scrbitmap);
  1031.  
  1032.     Machine->orientation = trueorientation;
  1033.  
  1034.     return;
  1035. }
  1036.  
  1037.  
  1038. #ifdef MAME_DEBUG
  1039. static void showtotalcolors(void)
  1040. {
  1041.     char *used;
  1042.     int i,l,x,y,total;
  1043.     char buf[40];
  1044.     int trueorientation;
  1045.  
  1046.  
  1047.     used = malloc(0x10000);
  1048.     if (!used) return;
  1049.  
  1050.     for (i = 0;i < 0x10000;i++)
  1051.         used[i] = 0;
  1052.  
  1053.     if (Machine->scrbitmap->depth == 16)
  1054.     {
  1055.         for (y = 0;y < Machine->scrbitmap->height;y++)
  1056.         {
  1057.             for (x = 0;x < Machine->scrbitmap->width;x++)
  1058.             {
  1059.                 used[((unsigned short *)Machine->scrbitmap->line[y])[x]] = 1;
  1060.             }
  1061.         }
  1062.     }
  1063.     else
  1064.     {
  1065.         for (y = 0;y < Machine->scrbitmap->height;y++)
  1066.         {
  1067.             for (x = 0;x < Machine->scrbitmap->width;x++)
  1068.             {
  1069.                 used[Machine->scrbitmap->line[y][x]] = 1;
  1070.             }
  1071.         }
  1072.     }
  1073.  
  1074.     total = 0;
  1075.     for (i = 0;i < 0x10000;i++)
  1076.         if (used[i]) total++;
  1077.  
  1078.     /* hack: force the display into standard orientation to avoid */
  1079.     /* rotating the text */
  1080.     trueorientation = Machine->orientation;
  1081.     Machine->orientation = Machine->ui_orientation;
  1082.  
  1083.     sprintf(buf,"%5d colors",total);
  1084.     l = strlen(buf);
  1085.     for (i = 0;i < l;i++)
  1086.         drawgfx(Machine->scrbitmap,Machine->uifont,buf[i],total>256?DT_COLOR_YELLOW:DT_COLOR_WHITE,0,0,Machine->uixmin+i*Machine->uifontwidth,Machine->uiymin,0,TRANSPARENCY_NONE,0);
  1087.  
  1088.     Machine->orientation = trueorientation;
  1089.  
  1090.     free(used);
  1091. }
  1092. #endif
  1093.  
  1094.  
  1095. static int setdipswitches(int selected)
  1096. {
  1097.     const char *menu_item[40];
  1098.     const char *menu_subitem[40];
  1099.     struct InputPort *entry[40];
  1100.     char flag[40];
  1101.     int i,sel;
  1102.     struct InputPort *in;
  1103.     int total;
  1104.     int arrowize;
  1105.  
  1106.  
  1107.     sel = selected - 1;
  1108.  
  1109.  
  1110.     in = Machine->input_ports;
  1111.  
  1112.     total = 0;
  1113.     while (in->type != IPT_END)
  1114.     {
  1115.         if ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_NAME && input_port_name(in) != 0 &&
  1116.                 (in->type & IPF_UNUSED) == 0 &&
  1117.                 !(!options.cheat && (in->type & IPF_CHEAT)))
  1118.         {
  1119.             entry[total] = in;
  1120.             menu_item[total] = input_port_name(in);
  1121.  
  1122.             total++;
  1123.         }
  1124.  
  1125.         in++;
  1126.     }
  1127.  
  1128.     if (total == 0) return 0;
  1129.  
  1130.     menu_item[total] = "Return to Main Menu";
  1131.     menu_item[total + 1] = 0;    /* terminate array */
  1132.     total++;
  1133.  
  1134.  
  1135.     for (i = 0;i < total;i++)
  1136.     {
  1137.         flag[i] = 0; /* TODO: flag the dip if it's not the real default */
  1138.         if (i < total - 1)
  1139.         {
  1140.             in = entry[i] + 1;
  1141.             while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1142.                     in->default_value != entry[i]->default_value)
  1143.                 in++;
  1144.  
  1145.             if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1146.                 menu_subitem[i] = "INVALID";
  1147.             else menu_subitem[i] = input_port_name(in);
  1148.         }
  1149.         else menu_subitem[i] = 0;    /* no subitem */
  1150.     }
  1151.  
  1152.     arrowize = 0;
  1153.     if (sel < total - 1)
  1154.     {
  1155.         in = entry[sel] + 1;
  1156.         while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1157.                 in->default_value != entry[sel]->default_value)
  1158.             in++;
  1159.  
  1160.         if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1161.             /* invalid setting: revert to a valid one */
  1162.             arrowize |= 1;
  1163.         else
  1164.         {
  1165.             if (((in-1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1166.                     !(!options.cheat && ((in-1)->type & IPF_CHEAT)))
  1167.                 arrowize |= 1;
  1168.         }
  1169.     }
  1170.     if (sel < total - 1)
  1171.     {
  1172.         in = entry[sel] + 1;
  1173.         while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1174.                 in->default_value != entry[sel]->default_value)
  1175.             in++;
  1176.  
  1177.         if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1178.             /* invalid setting: revert to a valid one */
  1179.             arrowize |= 2;
  1180.         else
  1181.         {
  1182.             if (((in+1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1183.                     !(!options.cheat && ((in+1)->type & IPF_CHEAT)))
  1184.                 arrowize |= 2;
  1185.         }
  1186.     }
  1187.  
  1188.     displaymenu(menu_item,menu_subitem,flag,sel,arrowize);
  1189.  
  1190.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  1191.     {
  1192.         if (sel < total - 1) sel++;
  1193.         else sel = 0;
  1194.     }
  1195.  
  1196.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  1197.     {
  1198.         if (sel > 0) sel--;
  1199.         else sel = total - 1;
  1200.     }
  1201.  
  1202.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_RIGHT,8))
  1203.     {
  1204.         if (sel < total - 1)
  1205.         {
  1206.             in = entry[sel] + 1;
  1207.             while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1208.                     in->default_value != entry[sel]->default_value)
  1209.                 in++;
  1210.  
  1211.             if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1212.                 /* invalid setting: revert to a valid one */
  1213.                 entry[sel]->default_value = (entry[sel]+1)->default_value & entry[sel]->mask;
  1214.             else
  1215.             {
  1216.                 if (((in+1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1217.                         !(!options.cheat && ((in+1)->type & IPF_CHEAT)))
  1218.                     entry[sel]->default_value = (in+1)->default_value & entry[sel]->mask;
  1219.             }
  1220.  
  1221.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1222.             need_to_clear_bitmap = 1;
  1223.         }
  1224.     }
  1225.  
  1226.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_LEFT,8))
  1227.     {
  1228.         if (sel < total - 1)
  1229.         {
  1230.             in = entry[sel] + 1;
  1231.             while ((in->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1232.                     in->default_value != entry[sel]->default_value)
  1233.                 in++;
  1234.  
  1235.             if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING)
  1236.                 /* invalid setting: revert to a valid one */
  1237.                 entry[sel]->default_value = (entry[sel]+1)->default_value & entry[sel]->mask;
  1238.             else
  1239.             {
  1240.                 if (((in-1)->type & ~IPF_MASK) == IPT_DIPSWITCH_SETTING &&
  1241.                         !(!options.cheat && ((in-1)->type & IPF_CHEAT)))
  1242.                     entry[sel]->default_value = (in-1)->default_value & entry[sel]->mask;
  1243.             }
  1244.  
  1245.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1246.             need_to_clear_bitmap = 1;
  1247.         }
  1248.     }
  1249.  
  1250.     if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  1251.     {
  1252.         if (sel == total - 1) sel = -1;
  1253.     }
  1254.  
  1255.     if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1256.         sel = -1;
  1257.  
  1258.     if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  1259.         sel = -2;
  1260.  
  1261.     if (sel == -1 || sel == -2)
  1262.     {
  1263.         /* tell updatescreen() to clean after us */
  1264.         need_to_clear_bitmap = 1;
  1265.     }
  1266.  
  1267.     return sel + 1;
  1268. }
  1269.  
  1270.  
  1271.  
  1272. static int setdefkeysettings(int selected)
  1273. {
  1274.     const char *menu_item[400];
  1275.     const char *menu_subitem[400];
  1276.     struct ipd *entry[400];
  1277.     char flag[400];
  1278.     int i,sel;
  1279.     struct ipd *in;
  1280.     int total;
  1281.     extern struct ipd inputport_defaults[];
  1282.  
  1283.  
  1284.     sel = selected - 1;
  1285.  
  1286.  
  1287.     if (Machine->input_ports == 0)
  1288.         return 0;
  1289.  
  1290.     in = inputport_defaults;
  1291.  
  1292.     total = 0;
  1293.     while (in->type != IPT_END)
  1294.     {
  1295.         if (in->name != 0 && in->keyboard != IP_KEY_NONE && (in->type & IPF_UNUSED) == 0
  1296.             && !(!options.cheat && (in->type & IPF_CHEAT)))
  1297.         {
  1298.             entry[total] = in;
  1299.             menu_item[total] = in->name;
  1300.  
  1301.             total++;
  1302.         }
  1303.  
  1304.         in++;
  1305.     }
  1306.  
  1307.     if (total == 0) return 0;
  1308.  
  1309.     menu_item[total] = "Return to Main Menu";
  1310.     menu_item[total + 1] = 0;    /* terminate array */
  1311.     total++;
  1312.  
  1313.     for (i = 0;i < total;i++)
  1314.     {
  1315.         if (i < total - 1)
  1316.             menu_subitem[i] = osd_key_name(entry[i]->keyboard);
  1317.         else menu_subitem[i] = 0;    /* no subitem */
  1318.         flag[i] = 0;
  1319.     }
  1320.  
  1321.     if (sel > 255)    /* are we waiting for a new key? */
  1322.     {
  1323.         int newkey;
  1324.  
  1325.  
  1326.         menu_subitem[sel & 0xff] = "    ";
  1327.         displaymenu(menu_item,menu_subitem,flag,sel & 0xff,3);
  1328.         newkey = osd_read_key_immediate();
  1329.         if (newkey != OSD_KEY_NONE)
  1330.         {
  1331.             sel &= 0xff;
  1332.  
  1333.             if (!osd_key_invalid(newkey))    /* don't use pseudo key code */
  1334.                 entry[sel]->keyboard = newkey;
  1335.  
  1336.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1337.             need_to_clear_bitmap = 1;
  1338.         }
  1339.  
  1340.         return sel + 1;
  1341.     }
  1342.  
  1343.  
  1344.     displaymenu(menu_item,menu_subitem,flag,sel,0);
  1345.  
  1346.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  1347.     {
  1348.         if (sel < total - 1) sel++;
  1349.         else sel = 0;
  1350.     }
  1351.  
  1352.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  1353.     {
  1354.         if (sel > 0) sel--;
  1355.         else sel = total - 1;
  1356.     }
  1357.  
  1358.     if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  1359.     {
  1360.         if (sel == total - 1) sel = -1;
  1361.         else
  1362.         {
  1363.             sel |= 0x100;    /* we'll ask for a key */
  1364.  
  1365.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1366.             need_to_clear_bitmap = 1;
  1367.         }
  1368.     }
  1369.  
  1370.     if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1371.         sel = -1;
  1372.  
  1373.     if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  1374.         sel = -2;
  1375.  
  1376.     if (sel == -1 || sel == -2)
  1377.     {
  1378.         /* tell updatescreen() to clean after us */
  1379.         need_to_clear_bitmap = 1;
  1380.     }
  1381.  
  1382.     return sel + 1;
  1383. }
  1384.  
  1385.  
  1386.  
  1387. int setdefjoysettings(int selected)
  1388. {
  1389.     const char *menu_item[400];
  1390.     const char *menu_subitem[400];
  1391.     struct ipd *entry[400];
  1392.     char flag[400];
  1393.     int i,sel;
  1394.     struct ipd *in;
  1395.     int total;
  1396.     extern struct ipd inputport_defaults[];
  1397.  
  1398.  
  1399.     sel = selected - 1;
  1400.  
  1401.  
  1402.     if (Machine->input_ports == 0)
  1403.         return 0;
  1404.  
  1405.     in = inputport_defaults;
  1406.  
  1407.     total = 0;
  1408.     while (in->type != IPT_END)
  1409.     {
  1410.         if (in->name != 0 && in->joystick != IP_JOY_NONE && (in->type & IPF_UNUSED) == 0
  1411.             && !(!options.cheat && (in->type & IPF_CHEAT)))
  1412.         {
  1413.             entry[total] = in;
  1414.             menu_item[total] = in->name;
  1415.  
  1416.             total++;
  1417.         }
  1418.  
  1419.         in++;
  1420.     }
  1421.  
  1422.     if (total == 0) return 0;
  1423.  
  1424.     menu_item[total] = "Return to Main Menu";
  1425.     menu_item[total + 1] = 0;    /* terminate array */
  1426.     total++;
  1427.  
  1428.     for (i = 0;i < total;i++)
  1429.     {
  1430.         if (i < total - 1)
  1431.             menu_subitem[i] = osd_joy_name(entry[i]->joystick);
  1432.         else menu_subitem[i] = 0;    /* no subitem */
  1433.         flag[i] = 0;
  1434.     }
  1435.  
  1436.     if (sel > 255)    /* are we waiting for a new key? */
  1437.     {
  1438.         int newjoy;
  1439.         int joyindex;
  1440.  
  1441.  
  1442.         menu_subitem[sel & 0xff] = "    ";
  1443.         displaymenu(menu_item,menu_subitem,flag,sel & 0xff,3);
  1444.  
  1445.         /* Check all possible joystick values for switch or button press */
  1446.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1447.         {
  1448.             sel &= 0xff;
  1449.             /* don't change the setting */
  1450.  
  1451.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1452.             need_to_clear_bitmap = 1;
  1453.         }
  1454.  
  1455.         /* Allows for "All buttons" */
  1456.         if (osd_key_pressed_memory(OSD_KEY_A))
  1457.         {
  1458.             sel &= 0xff;
  1459.             entry[sel]->joystick = OSD_JOY_FIRE;
  1460.  
  1461.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1462.             need_to_clear_bitmap = 1;
  1463.         }
  1464.         if (osd_key_pressed_memory(OSD_KEY_B))
  1465.         {
  1466.             sel &= 0xff;
  1467.             entry[sel]->joystick = OSD_JOY2_FIRE;
  1468.  
  1469.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1470.             need_to_clear_bitmap = 1;
  1471.         }
  1472.         /* Clears entry "None" */
  1473.         if (osd_key_pressed_memory(OSD_KEY_N))
  1474.         {
  1475.             sel &= 0xff;
  1476.             entry[sel]->joystick = 0;
  1477.  
  1478.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1479.             need_to_clear_bitmap = 1;
  1480.         }
  1481.  
  1482.         for (joyindex = 1; joyindex < OSD_MAX_JOY; joyindex++)
  1483.         {
  1484.             if (osd_joy_pressed(joyindex))
  1485.             {
  1486.                 sel &= 0xff;
  1487.                 entry[sel]->joystick = joyindex;
  1488.  
  1489.                 /* tell updatescreen() to clean after us (in case the window changes size) */
  1490.                 need_to_clear_bitmap = 1;
  1491.                 break;
  1492.             }
  1493.         }
  1494.  
  1495.         return sel + 1;
  1496.     }
  1497.  
  1498.  
  1499.     displaymenu(menu_item,menu_subitem,flag,sel,0);
  1500.  
  1501.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  1502.     {
  1503.         if (sel < total - 1) sel++;
  1504.         else sel = 0;
  1505.     }
  1506.  
  1507.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  1508.     {
  1509.         if (sel > 0) sel--;
  1510.         else sel = total - 1;
  1511.     }
  1512.  
  1513.     if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  1514.     {
  1515.         if (sel == total - 1) sel = -1;
  1516.         else
  1517.         {
  1518.             sel |= 0x100;    /* we'll ask for a key */
  1519.  
  1520.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1521.             need_to_clear_bitmap = 1;
  1522.         }
  1523.     }
  1524.  
  1525.     if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1526.         sel = -1;
  1527.  
  1528.     if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  1529.         sel = -2;
  1530.  
  1531.     if (sel == -1 || sel == -2)
  1532.     {
  1533.         /* tell updatescreen() to clean after us */
  1534.         need_to_clear_bitmap = 1;
  1535.     }
  1536.  
  1537.     return sel + 1;
  1538. }
  1539.  
  1540.  
  1541.  
  1542. static int setkeysettings(int selected)
  1543. {
  1544.     const char *menu_item[40];
  1545.     const char *menu_subitem[40];
  1546.     struct InputPort *entry[40];
  1547.     char flag[40];
  1548.     int i,sel;
  1549.     struct InputPort *in;
  1550.     int total;
  1551.  
  1552.  
  1553.     sel = selected - 1;
  1554.  
  1555.  
  1556.     if (Machine->input_ports == 0)
  1557.         return 0;
  1558.  
  1559.     in = Machine->input_ports;
  1560.  
  1561.     total = 0;
  1562.     while (in->type != IPT_END)
  1563.     {
  1564.         if (input_port_name(in) != 0 && input_port_key(in) != IP_KEY_NONE)
  1565.         {
  1566.             entry[total] = in;
  1567.             menu_item[total] = input_port_name(in);
  1568.  
  1569.             total++;
  1570.         }
  1571.  
  1572.         in++;
  1573.     }
  1574.  
  1575.     if (total == 0) return 0;
  1576.  
  1577.     menu_item[total] = "Return to Main Menu";
  1578.     menu_item[total + 1] = 0;    /* terminate array */
  1579.     total++;
  1580.  
  1581.     for (i = 0;i < total;i++)
  1582.     {
  1583.         if (i < total - 1)
  1584.         {
  1585.             menu_subitem[i] = osd_key_name(input_port_key(entry[i]));
  1586.             /* If the key isn't the default, flag it */
  1587.             if (entry[i]->keyboard != IP_KEY_DEFAULT)
  1588.                 flag[i] = 1;
  1589.             else
  1590.                 flag[i] = 0;
  1591.  
  1592.         }
  1593.         else menu_subitem[i] = 0;    /* no subitem */
  1594.     }
  1595.  
  1596.     if (sel > 255)    /* are we waiting for a new key? */
  1597.     {
  1598.         int newkey;
  1599.  
  1600.  
  1601.         menu_subitem[sel & 0xff] = "    ";
  1602.         displaymenu(menu_item,menu_subitem,flag,sel & 0xff,3);
  1603.         newkey = osd_read_key_immediate();
  1604.         if (newkey != OSD_KEY_NONE)
  1605.         {
  1606.             sel &= 0xff;
  1607.  
  1608.             if (osd_key_invalid(newkey))    /* pseudo key code? */
  1609.                 newkey = IP_KEY_DEFAULT;
  1610.  
  1611.             entry[sel]->keyboard = newkey;
  1612.  
  1613.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1614.             need_to_clear_bitmap = 1;
  1615.         }
  1616.  
  1617.         return sel + 1;
  1618.     }
  1619.  
  1620.  
  1621.     displaymenu(menu_item,menu_subitem,flag,sel,0);
  1622.  
  1623.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  1624.     {
  1625.         if (sel < total - 1) sel++;
  1626.         else sel = 0;
  1627.     }
  1628.  
  1629.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  1630.     {
  1631.         if (sel > 0) sel--;
  1632.         else sel = total - 1;
  1633.     }
  1634.  
  1635.     if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  1636.     {
  1637.         if (sel == total - 1) sel = -1;
  1638.         else
  1639.         {
  1640.             sel |= 0x100;    /* we'll ask for a key */
  1641.  
  1642.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1643.             need_to_clear_bitmap = 1;
  1644.         }
  1645.     }
  1646.  
  1647.     if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1648.         sel = -1;
  1649.  
  1650.     if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  1651.         sel = -2;
  1652.  
  1653.     if (sel == -1 || sel == -2)
  1654.     {
  1655.         /* tell updatescreen() to clean after us */
  1656.         need_to_clear_bitmap = 1;
  1657.     }
  1658.  
  1659.     return sel + 1;
  1660. }
  1661.  
  1662.  
  1663.  
  1664. static int setjoysettings(int selected)
  1665. {
  1666.     const char *menu_item[40];
  1667.     const char *menu_subitem[40];
  1668.     struct InputPort *entry[40];
  1669.     char flag[40];
  1670.     int i,sel;
  1671.     struct InputPort *in;
  1672.     int total;
  1673.  
  1674.  
  1675.     sel = selected - 1;
  1676.  
  1677.  
  1678.     if (Machine->input_ports == 0)
  1679.         return 0;
  1680.  
  1681.     in = Machine->input_ports;
  1682.  
  1683.     total = 0;
  1684.     while (in->type != IPT_END)
  1685.     {
  1686.         if (input_port_name(in) != 0 && input_port_joy(in) != IP_JOY_NONE)
  1687.         {
  1688.             entry[total] = in;
  1689.             menu_item[total] = input_port_name(in);
  1690.  
  1691.             total++;
  1692.         }
  1693.  
  1694.         in++;
  1695.     }
  1696.  
  1697.     if (total == 0) return 0;
  1698.  
  1699.     menu_item[total] = "Return to Main Menu";
  1700.     menu_item[total + 1] = 0;    /* terminate array */
  1701.     total++;
  1702.  
  1703.     for (i = 0;i < total;i++)
  1704.     {
  1705.         if (i < total - 1)
  1706.         {
  1707.             menu_subitem[i] = osd_joy_name(input_port_joy(entry[i]));
  1708.             if (entry[i]->joystick != IP_JOY_DEFAULT)
  1709.                 flag[i] = 1;
  1710.             else
  1711.                 flag[i] = 0;
  1712.         }
  1713.         else menu_subitem[i] = 0;    /* no subitem */
  1714.     }
  1715.  
  1716.     if (sel > 255)    /* are we waiting for a new joy direction? */
  1717.     {
  1718.         int newjoy;
  1719.         int joyindex;
  1720.  
  1721.  
  1722.         menu_subitem[sel & 0xff] = "    ";
  1723.         displaymenu(menu_item,menu_subitem,flag,sel & 0xff,3);
  1724.  
  1725.         /* Check all possible joystick values for switch or button press */
  1726.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1727.         {
  1728.             sel &= 0xff;
  1729.             entry[sel]->joystick = IP_JOY_DEFAULT;
  1730.  
  1731.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1732.             need_to_clear_bitmap = 1;
  1733.         }
  1734.  
  1735.         /* Allows for "All buttons" */
  1736.         if (osd_key_pressed_memory(OSD_KEY_A))
  1737.         {
  1738.             sel &= 0xff;
  1739.             entry[sel]->joystick = OSD_JOY_FIRE;
  1740.  
  1741.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1742.             need_to_clear_bitmap = 1;
  1743.         }
  1744.         if (osd_key_pressed_memory(OSD_KEY_B))
  1745.         {
  1746.             sel &= 0xff;
  1747.             entry[sel]->joystick = OSD_JOY2_FIRE;
  1748.  
  1749.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1750.             need_to_clear_bitmap = 1;
  1751.         }
  1752.         /* Clears entry "None" */
  1753.         if (osd_key_pressed_memory(OSD_KEY_N))
  1754.         {
  1755.             sel &= 0xff;
  1756.             entry[sel]->joystick = 0;
  1757.  
  1758.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1759.             need_to_clear_bitmap = 1;
  1760.         }
  1761.  
  1762.         for (joyindex = 1; joyindex < OSD_MAX_JOY; joyindex++)
  1763.         {
  1764.             if (osd_joy_pressed(joyindex))
  1765.             {
  1766.                 sel &= 0xff;
  1767.                 entry[sel]->joystick = joyindex;
  1768.  
  1769.                 /* tell updatescreen() to clean after us (in case the window changes size) */
  1770.                 need_to_clear_bitmap = 1;
  1771.                 break;
  1772.             }
  1773.         }
  1774.  
  1775.         return sel + 1;
  1776.     }
  1777.  
  1778.  
  1779.     displaymenu(menu_item,menu_subitem,flag,sel,0);
  1780.  
  1781.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  1782.     {
  1783.         if (sel < total - 1) sel++;
  1784.         else sel = 0;
  1785.     }
  1786.  
  1787.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  1788.     {
  1789.         if (sel > 0) sel--;
  1790.         else sel = total - 1;
  1791.     }
  1792.  
  1793.     if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  1794.     {
  1795.         if (sel == total - 1) sel = -1;
  1796.         else
  1797.         {
  1798.             sel |= 0x100;    /* we'll ask for a joy */
  1799.  
  1800.             /* tell updatescreen() to clean after us (in case the window changes size) */
  1801.             need_to_clear_bitmap = 1;
  1802.         }
  1803.     }
  1804.  
  1805.     if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1806.         sel = -1;
  1807.  
  1808.     if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  1809.         sel = -2;
  1810.  
  1811.     if (sel == -1 || sel == -2)
  1812.     {
  1813.         /* tell updatescreen() to clean after us */
  1814.         need_to_clear_bitmap = 1;
  1815.     }
  1816.  
  1817.     return sel + 1;
  1818. }
  1819.  
  1820.  
  1821. static int calibratejoysticks(int selected)
  1822. {
  1823.     char *msg;
  1824.     char buf[2048];
  1825.     int sel;
  1826.     static int calibration_started = 0;
  1827.  
  1828.     sel = selected - 1;
  1829.  
  1830.     if (calibration_started == 0)
  1831.     {
  1832.         osd_joystick_start_calibration();
  1833.         calibration_started = 1;
  1834.         strcpy (buf, "");
  1835.     }
  1836.  
  1837.     if (sel > 255) /* Waiting for the user to acknowledge joystick movement */
  1838.     {
  1839.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT)
  1840.                 || osd_key_pressed_memory (OSD_KEY_CANCEL))
  1841.         {
  1842.             calibration_started = 0;
  1843.             sel = -1;
  1844.         }
  1845.         else if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  1846.         {
  1847.             osd_joystick_calibrate();
  1848.             sel &= 0xff;
  1849.         }
  1850.  
  1851.         displaymessagewindow(buf);
  1852.     }
  1853.     else
  1854.     {
  1855.         msg = osd_joystick_calibrate_next();
  1856.         need_to_clear_bitmap = 1;
  1857.         if (msg == 0)
  1858.         {
  1859.             calibration_started = 0;
  1860.             osd_joystick_end_calibration();
  1861.             sel = -1;
  1862.         }
  1863.         else
  1864.         {
  1865.             strcpy (buf, msg);
  1866.             displaymessagewindow(buf);
  1867.             sel |= 0x100;
  1868.         }
  1869.     }
  1870.  
  1871.     if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  1872.         sel = -2;
  1873.  
  1874.     if (sel == -1 || sel == -2)
  1875.     {
  1876.         /* tell updatescreen() to clean after us */
  1877.         need_to_clear_bitmap = 1;
  1878.     }
  1879.  
  1880.     return sel + 1;
  1881. }
  1882.  
  1883.  
  1884. static int settraksettings(int selected)
  1885. {
  1886.     const char *menu_item[40];
  1887.     const char *menu_subitem[40];
  1888.     struct InputPort *entry[40];
  1889.     int i,sel;
  1890.     struct InputPort *in;
  1891.     int total,total2;
  1892.     int arrowize;
  1893.  
  1894.  
  1895.     sel = selected - 1;
  1896.  
  1897.  
  1898.     if (Machine->input_ports == 0)
  1899.         return 0;
  1900.  
  1901.     in = Machine->input_ports;
  1902.  
  1903.     /* Count the total number of analog controls */
  1904.     total = 0;
  1905.     while (in->type != IPT_END)
  1906.     {
  1907.         if (((in->type & 0xff) > IPT_ANALOG_START) && ((in->type & 0xff) < IPT_ANALOG_END)
  1908.                 && !(!options.cheat && (in->type & IPF_CHEAT)))
  1909.         {
  1910.             entry[total] = in;
  1911.             total++;
  1912.         }
  1913.         in++;
  1914.     }
  1915.  
  1916.     if (total == 0) return 0;
  1917.  
  1918.     /* Each analog control has 3 entries - key & joy delta, reverse, sensitivity */
  1919.  
  1920. #define ENTRIES 3
  1921.  
  1922.     total2 = total * ENTRIES;
  1923.  
  1924.     menu_item[total2] = "Return to Main Menu";
  1925.     menu_item[total2 + 1] = 0;    /* terminate array */
  1926.     total2++;
  1927.  
  1928.     arrowize = 0;
  1929.     for (i = 0;i < total2;i++)
  1930.     {
  1931.         if (i < total2 - 1)
  1932.         {
  1933.             char label[30][40];
  1934.             char setting[30][40];
  1935.             int sensitivity,delta;
  1936.             int reverse;
  1937.  
  1938.             strcpy (label[i], input_port_name(entry[i/ENTRIES]));
  1939.             sensitivity = IP_GET_SENSITIVITY(entry[i/ENTRIES]);
  1940.             delta = IP_GET_DELTA(entry[i/ENTRIES]);
  1941.             reverse = (entry[i/ENTRIES]->type & IPF_REVERSE);
  1942.  
  1943.             switch (i%ENTRIES)
  1944.             {
  1945.                 case 0:
  1946.                     strcat (label[i], " Key/Joy Delta");
  1947.                     sprintf(setting[i],"%d",delta);
  1948.                     if (i == sel) arrowize = 3;
  1949.                     break;
  1950.                 case 1:
  1951.                     strcat (label[i], " Reverse");
  1952.                     if (reverse)
  1953.                         sprintf(setting[i],"On");
  1954.                     else
  1955.                         sprintf(setting[i],"Off");
  1956.                     if (i == sel) arrowize = 3;
  1957.                     break;
  1958.                 case 2:
  1959.                     strcat (label[i], " Sensitivity");
  1960.                     sprintf(setting[i],"%3d%%",sensitivity);
  1961.                     if (i == sel) arrowize = 3;
  1962.                     break;
  1963.             }
  1964.  
  1965.             menu_item[i] = label[i];
  1966.             menu_subitem[i] = setting[i];
  1967.  
  1968.             in++;
  1969.         }
  1970.         else menu_subitem[i] = 0;    /* no subitem */
  1971.     }
  1972.  
  1973.     displaymenu(menu_item,menu_subitem,0,sel,arrowize);
  1974.  
  1975.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  1976.     {
  1977.         if (sel < total2 - 1) sel++;
  1978.         else sel = 0;
  1979.     }
  1980.  
  1981.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  1982.     {
  1983.         if (sel > 0) sel--;
  1984.         else sel = total2 - 1;
  1985.     }
  1986.  
  1987.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_LEFT,8))
  1988.     {
  1989.         if ((sel % ENTRIES) == 0)
  1990.         /* keyboard/joystick delta */
  1991.         {
  1992.             int val = IP_GET_DELTA(entry[sel/ENTRIES]);
  1993.  
  1994.             val --;
  1995.             if (val < 1) val = 1;
  1996.             IP_SET_DELTA(entry[sel/ENTRIES],val);
  1997.         }
  1998.         else if ((sel % ENTRIES) == 1)
  1999.         /* reverse */
  2000.         {
  2001.             int reverse = entry[sel/ENTRIES]->type & IPF_REVERSE;
  2002.             if (reverse)
  2003.                 reverse=0;
  2004.             else
  2005.                 reverse=IPF_REVERSE;
  2006.             entry[sel/ENTRIES]->type &= ~IPF_REVERSE;
  2007.             entry[sel/ENTRIES]->type |= reverse;
  2008.         }
  2009.         else if ((sel % ENTRIES) == 2)
  2010.         /* sensitivity */
  2011.         {
  2012.             int val = IP_GET_SENSITIVITY(entry[sel/ENTRIES]);
  2013.  
  2014.             val --;
  2015.             if (val < 1) val = 1;
  2016.             IP_SET_SENSITIVITY(entry[sel/ENTRIES],val);
  2017.         }
  2018.     }
  2019.  
  2020.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_RIGHT,8))
  2021.     {
  2022.         if ((sel % ENTRIES) == 0)
  2023.         /* keyboard/joystick delta */
  2024.         {
  2025.             int val = IP_GET_DELTA(entry[sel/ENTRIES]);
  2026.  
  2027.             val ++;
  2028.             if (val > 255) val = 255;
  2029.             IP_SET_DELTA(entry[sel/ENTRIES],val);
  2030.         }
  2031.         else if ((sel % ENTRIES) == 1)
  2032.         /* reverse */
  2033.         {
  2034.             int reverse = entry[sel/ENTRIES]->type & IPF_REVERSE;
  2035.             if (reverse)
  2036.                 reverse=0;
  2037.             else
  2038.                 reverse=IPF_REVERSE;
  2039.             entry[sel/ENTRIES]->type &= ~IPF_REVERSE;
  2040.             entry[sel/ENTRIES]->type |= reverse;
  2041.         }
  2042.         else if ((sel % ENTRIES) == 2)
  2043.         /* sensitivity */
  2044.         {
  2045.             int val = IP_GET_SENSITIVITY(entry[sel/ENTRIES]);
  2046.  
  2047.             val ++;
  2048.             if (val > 255) val = 255;
  2049.             IP_SET_SENSITIVITY(entry[sel/ENTRIES],val);
  2050.         }
  2051.     }
  2052.  
  2053.     if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  2054.     {
  2055.         if (sel == total2 - 1) sel = -1;
  2056.     }
  2057.  
  2058.     if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  2059.         sel = -1;
  2060.  
  2061.     if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  2062.         sel = -2;
  2063.  
  2064.     if (sel == -1 || sel == -2)
  2065.     {
  2066.         /* tell updatescreen() to clean after us */
  2067.         need_to_clear_bitmap = 1;
  2068.     }
  2069.  
  2070.     return sel + 1;
  2071. }
  2072.  
  2073. static int mame_stats(int selected)
  2074. {
  2075.     char temp[10];
  2076.     char buf[2048];
  2077.     int sel;
  2078.  
  2079.  
  2080.     sel = selected - 1;
  2081.  
  2082.     strcpy(buf, "Tickets dispensed: ");
  2083.     if (!dispensed_tickets)
  2084.         strcat (buf, "NA\n\n");
  2085.     else
  2086.     {
  2087.         sprintf (temp, "%d\n\n", dispensed_tickets);
  2088.         strcat (buf, temp);
  2089.     }
  2090.  
  2091.     strcat (buf, "Coin A: ");
  2092.     if (!coins[0])
  2093.         strcat (buf, "NA\n");
  2094.     else
  2095.     {
  2096.         sprintf (temp, "%d\n", coins[0]);
  2097.         strcat (buf, temp);
  2098.     }
  2099.  
  2100.     strcat (buf, "Coin B: ");
  2101.     if (!coins[1])
  2102.         strcat (buf, "NA\n");
  2103.     else
  2104.     {
  2105.         sprintf (temp, "%d\n", coins[1]);
  2106.         strcat (buf, temp);
  2107.     }
  2108.  
  2109.     strcat (buf, "Coin C: ");
  2110.     if (!coins[2])
  2111.         strcat (buf, "NA\n");
  2112.     else
  2113.     {
  2114.         sprintf (temp, "%d\n", coins[2]);
  2115.         strcat (buf, temp);
  2116.     }
  2117.  
  2118.     {
  2119.         /* menu system, use the normal menu keys */
  2120.         strcat(buf,"\n\t\x1a Return to Main Menu \x1b");
  2121.  
  2122.         displaymessagewindow(buf);
  2123.  
  2124.         if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  2125.             sel = -1;
  2126.  
  2127.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  2128.             sel = -1;
  2129.  
  2130.         if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  2131.             sel = -2;
  2132.     }
  2133.  
  2134.     if (sel == -1 || sel == -2)
  2135.     {
  2136.         /* tell updatescreen() to clean after us */
  2137.         need_to_clear_bitmap = 1;
  2138.     }
  2139.  
  2140.     return sel + 1;
  2141. }
  2142.  
  2143. int showcopyright(void)
  2144. {
  2145.     int done;
  2146.     char buf[] =
  2147.             "Do not distribute the source code and/or the executable "
  2148.             "application with any rom images.\n"
  2149.             "Doing as such will harm any further development of mame and could "
  2150.             "result in legal action being taken by the lawful copyright holders "
  2151.             "of any rom images.\n"
  2152.             "\n"
  2153.             "IF YOU DON'T AGREE WITH THE ABOVE, PRESS ESC.\n"
  2154.             "If you agree, type OK.";
  2155.  
  2156.     displaymessagewindow(buf);
  2157. #ifdef AMIGA
  2158.         osd_update_video_and_audio();
  2159. #endif
  2160.  
  2161.     done = 0;
  2162.     do
  2163.     {
  2164. #ifndef AMIGA
  2165.         osd_update_video_and_audio();
  2166. #endif
  2167.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) ||
  2168.                 osd_key_pressed_memory(OSD_KEY_CANCEL))
  2169.             return 1;
  2170.         if (osd_key_pressed_memory(OSD_KEY_O) ||
  2171.                 osd_key_pressed_memory(OSD_KEY_UI_LEFT))
  2172.             done = 1;
  2173.         if (done == 1 && (osd_key_pressed_memory(OSD_KEY_K) ||
  2174.                 osd_key_pressed_memory(OSD_KEY_UI_RIGHT)))
  2175.             done = 2;
  2176.     } while (done < 2);
  2177.  
  2178.     osd_clearbitmap(Machine->scrbitmap);
  2179.     osd_update_video_and_audio();
  2180.  
  2181.     return 0;
  2182. }
  2183.  
  2184. static int displaycredits(int selected)
  2185. {
  2186.     char buf[2048];
  2187.     int sel;
  2188.  
  2189.  
  2190.     sel = selected - 1;
  2191.  
  2192.     sprintf(buf,"The following people\ncontributed to this driver:\n\n%s",Machine->gamedrv->credits);
  2193.  
  2194.     if (sel == -1)
  2195.     {
  2196.         /* startup info, ask for any key */
  2197.         strcat(buf,"\n\tPress any key");
  2198.  
  2199.         displaymessagewindow(buf);
  2200.  
  2201.         sel = 0;
  2202.         if (osd_key_pressed_memory (OSD_KEY_ANY))
  2203.             sel = -1;
  2204.     }
  2205.     else
  2206.     {
  2207.         /* menu system, use the normal menu keys */
  2208.         strcat(buf,"\n\t\x1a Return to Main Menu \x1b");
  2209.  
  2210.         displaymessagewindow(buf);
  2211.  
  2212.         if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  2213.             sel = -1;
  2214.  
  2215.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  2216.             sel = -1;
  2217.  
  2218.         if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  2219.             sel = -2;
  2220.     }
  2221.  
  2222.     if (sel == -1 || sel == -2)
  2223.     {
  2224.         /* tell updatescreen() to clean after us */
  2225.         need_to_clear_bitmap = 1;
  2226.     }
  2227.  
  2228.     return sel + 1;
  2229. }
  2230.  
  2231. void showcredits(void)
  2232. {
  2233.     while (displaycredits(0) == 1)
  2234.         osd_update_video_and_audio();
  2235.  
  2236.     osd_clearbitmap(Machine->scrbitmap);
  2237.     osd_update_video_and_audio();
  2238. }
  2239.  
  2240. static int displaygameinfo(int selected)
  2241. {
  2242.     int i;
  2243.     char buf[2048];
  2244.     int sel;
  2245.  
  2246.  
  2247.     sel = selected - 1;
  2248.  
  2249.  
  2250.     sprintf(buf,"%s\n%s %s\n\nCPU:\n",Machine->gamedrv->description,Machine->gamedrv->year,Machine->gamedrv->manufacturer);
  2251.     i = 0;
  2252.     while (i < MAX_CPU && Machine->drv->cpu[i].cpu_type)
  2253.     {
  2254.         sprintf(&buf[strlen(buf)],"%s %d.%06d MHz",
  2255.                 cputype_name(Machine->drv->cpu[i].cpu_type),
  2256.                 Machine->drv->cpu[i].cpu_clock / 1000000,
  2257.                 Machine->drv->cpu[i].cpu_clock % 1000000);
  2258.  
  2259.         if (Machine->drv->cpu[i].cpu_type & CPU_AUDIO_CPU)
  2260.             strcat(buf," (sound)");
  2261.  
  2262.         strcat(buf,"\n");
  2263.  
  2264.         i++;
  2265.     }
  2266.  
  2267.     strcat(buf,"\nSound");
  2268.     if (Machine->drv->sound_attributes & SOUND_SUPPORTS_STEREO)
  2269.         sprintf(&buf[strlen(buf)]," (stereo)");
  2270.     strcat(buf,":\n");
  2271.  
  2272.     i = 0;
  2273.     while (i < MAX_SOUND && Machine->drv->sound[i].sound_type)
  2274.     {
  2275.         if (sound_num(&Machine->drv->sound[i]))
  2276.             sprintf(&buf[strlen(buf)],"%dx",sound_num(&Machine->drv->sound[i]));
  2277.  
  2278.         sprintf(&buf[strlen(buf)],"%s",sound_name(&Machine->drv->sound[i]));
  2279.  
  2280.         if (sound_clock(&Machine->drv->sound[i]))
  2281.             sprintf(&buf[strlen(buf)]," %d.%06d MHz",
  2282.                     sound_clock(&Machine->drv->sound[i]) / 1000000,
  2283.                     sound_clock(&Machine->drv->sound[i]) % 1000000);
  2284.  
  2285.         strcat(buf,"\n");
  2286.  
  2287.         i++;
  2288.     }
  2289.  
  2290.     if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
  2291.         sprintf(&buf[strlen(buf)],"\nVector Game\n");
  2292.     else
  2293.     {
  2294.         int pixelx,pixely,tmax,tmin,rem;
  2295.  
  2296.         pixelx = 4 * (Machine->drv->visible_area.max_y - Machine->drv->visible_area.min_y + 1);
  2297.         pixely = 3 * (Machine->drv->visible_area.max_x - Machine->drv->visible_area.min_x + 1);
  2298.  
  2299.         /* calculate MCD */
  2300.         if (pixelx >= pixely)
  2301.         {
  2302.             tmax = pixelx;
  2303.             tmin = pixely;
  2304.         }
  2305.         else
  2306.         {
  2307.             tmax = pixely;
  2308.             tmin = pixelx;
  2309.         }
  2310.         while ( (rem = tmax % tmin) )
  2311.         {
  2312.             tmax = tmin;
  2313.             tmin = rem;
  2314.         }
  2315.         /* tmin is now the MCD */
  2316.  
  2317.         pixelx /= tmin;
  2318.         pixely /= tmin;
  2319.  
  2320.         sprintf(&buf[strlen(buf)],"\nScreen resolution:\n");
  2321.         sprintf(&buf[strlen(buf)],"%d x %d (%s) %d Hz\npixel aspect ratio %d:%d\n",
  2322.                 Machine->drv->visible_area.max_x - Machine->drv->visible_area.min_x + 1,
  2323.                 Machine->drv->visible_area.max_y - Machine->drv->visible_area.min_y + 1,
  2324.                 (Machine->gamedrv->orientation & ORIENTATION_SWAP_XY) ? "V" : "H",
  2325.                 Machine->drv->frames_per_second,
  2326.                 pixelx,pixely);
  2327.         sprintf(&buf[strlen(buf)],"%d colors ",Machine->drv->total_colors);
  2328.         if (Machine->drv->video_attributes & VIDEO_SUPPORTS_16BIT)
  2329.             strcat(buf,"(16-bit required)\n");
  2330.         else if (Machine->drv->video_attributes & VIDEO_MODIFIES_PALETTE)
  2331.             strcat(buf,"(dynamic)\n");
  2332.         else strcat(buf,"(static)\n");
  2333.     }
  2334.  
  2335.  
  2336.     if (sel == -1)
  2337.     {
  2338.         /* startup info, print MAME version and ask for any key */
  2339.         strcat(buf,"\n\tMAME ");    /* \t means that the line will be centered */
  2340.         strcat(buf,build_version);
  2341.         strcat(buf,"\n\tPress any key");
  2342.  
  2343.         drawbox(0,0,Machine->uiwidth,Machine->uiheight);
  2344.         displaymessagewindow(buf);
  2345.  
  2346.         sel = 0;
  2347.         if (osd_key_pressed_memory (OSD_KEY_ANY))
  2348.             sel = -1;
  2349.     }
  2350.     else
  2351.     {
  2352.         /* menu system, use the normal menu keys */
  2353.         strcat(buf,"\n\t\x1a Return to Main Menu \x1b");
  2354.  
  2355.         displaymessagewindow(buf);
  2356.  
  2357.         if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  2358.             sel = -1;
  2359.  
  2360.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  2361.             sel = -1;
  2362.  
  2363.         if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  2364.             sel = -2;
  2365.     }
  2366.  
  2367.     if (sel == -1 || sel == -2)
  2368.     {
  2369.         /* tell updatescreen() to clean after us */
  2370.         need_to_clear_bitmap = 1;
  2371.     }
  2372.  
  2373.     return sel + 1;
  2374. }
  2375.  
  2376. int showgamewarnings(void)
  2377. {
  2378.     int i;
  2379.     char buf[2048];
  2380.  
  2381.     if (Machine->gamedrv->flags)
  2382.     {
  2383.         int done;
  2384.  
  2385.  
  2386.         strcpy(buf, "There are known problems with this game:\n\n");
  2387.  
  2388.         if (Machine->gamedrv->flags & GAME_IMPERFECT_COLORS)
  2389.         {
  2390.             strcat(buf, "The colors aren't 100% accurate.\n");
  2391.         }
  2392.  
  2393.         if (Machine->gamedrv->flags & GAME_WRONG_COLORS)
  2394.         {
  2395.             strcat(buf, "The colors are completely wrong.\n");
  2396.         }
  2397.  
  2398.         if (Machine->gamedrv->flags & GAME_IMPERFECT_SOUND)
  2399.         {
  2400.             strcat(buf, "The sound emulation isn't 100% accurate.\n");
  2401.         }
  2402.  
  2403.         if (Machine->gamedrv->flags & GAME_NO_SOUND)
  2404.         {
  2405.             strcat(buf, "The game lacks sound.\n");
  2406.         }
  2407.  
  2408.         if (Machine->gamedrv->flags & GAME_NOT_WORKING)
  2409.         {
  2410.             const struct GameDriver *main;
  2411.             int foundworking;
  2412.  
  2413.             strcpy(buf,"THIS GAME DOESN'T WORK PROPERLY");
  2414.             if (Machine->gamedrv->clone_of) main = Machine->gamedrv->clone_of;
  2415.             else main = Machine->gamedrv;
  2416.  
  2417.             foundworking = 0;
  2418.             i = 0;
  2419.             while (drivers[i])
  2420.             {
  2421.                 if (drivers[i] == main || drivers[i]->clone_of == main)
  2422.                 {
  2423.                     if ((drivers[i]->flags & GAME_NOT_WORKING) == 0)
  2424.                     {
  2425.                         if (foundworking == 0)
  2426.                             strcat(buf,"\n\nThere are clones of this game which work. They are:\n\n");
  2427.                         foundworking = 1;
  2428.  
  2429.                         sprintf(&buf[strlen(buf)],"%s\n",drivers[i]->name);
  2430.                     }
  2431.                 }
  2432.                 i++;
  2433.             }
  2434.         }
  2435.  
  2436.         strcat(buf,"\n\nType OK to continue");
  2437.  
  2438.         displaymessagewindow(buf);
  2439.  
  2440.         done = 0;
  2441.         do
  2442.         {
  2443.             osd_update_video_and_audio();
  2444.             if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) ||
  2445.                     osd_key_pressed_memory(OSD_KEY_CANCEL))
  2446.                 return 1;
  2447.             if (osd_key_pressed_memory(OSD_KEY_O) ||
  2448.                     osd_key_pressed_memory(OSD_KEY_UI_LEFT))
  2449.                 done = 1;
  2450.             if (done == 1 && (osd_key_pressed_memory(OSD_KEY_K) ||
  2451.                     osd_key_pressed_memory(OSD_KEY_UI_RIGHT)))
  2452.                 done = 2;
  2453.         } while (done < 2);
  2454.     }
  2455.  
  2456.  
  2457.     osd_clearbitmap(Machine->scrbitmap);
  2458.  
  2459.     while (displaygameinfo(0) == 1)
  2460.         osd_update_video_and_audio();
  2461.  
  2462.     osd_clearbitmap(Machine->scrbitmap);
  2463.     /* make sure that the screen is really cleared, in case autoframeskip kicked in */
  2464.     osd_update_video_and_audio();
  2465.     osd_update_video_and_audio();
  2466.     osd_update_video_and_audio();
  2467.     osd_update_video_and_audio();
  2468.  
  2469.     return 0;
  2470. }
  2471.  
  2472. /* Word-wraps the text in the specified buffer to fit in maxwidth characters per line.
  2473.    The contents of the buffer are modified.
  2474.    Known limitations: Words longer than maxwidth cause the function to fail. */
  2475. static void wordwrap_text_buffer (char *buffer, int maxwidth)
  2476. {
  2477.     int width = 0;
  2478.  
  2479.     while (*buffer)
  2480.     {
  2481.         if (*buffer == '\n')
  2482.         {
  2483.             buffer++;
  2484.             width = 0;
  2485.             continue;
  2486.         }
  2487.  
  2488.         width++;
  2489.  
  2490.         if (width > maxwidth)
  2491.         {
  2492.             /* backtrack until a space is found */
  2493.             while (*buffer != ' ')
  2494.             {
  2495.                 buffer--;
  2496.                 width--;
  2497.             }
  2498.             if (width < 1) return;    /* word too long */
  2499.  
  2500.             /* replace space with a newline */
  2501.             *buffer = '\n';
  2502.         }
  2503.         else
  2504.             buffer++;
  2505.     }
  2506. }
  2507.  
  2508. static int count_lines_in_buffer (char *buffer)
  2509. {
  2510.     int lines = 0;
  2511.     char c;
  2512.  
  2513.     while ( (c = *buffer++) )
  2514.         if (c == '\n') lines++;
  2515.  
  2516.     return lines;
  2517. }
  2518.  
  2519. /* Display lines from buffer, starting with line 'scroll', in a width x height text window */
  2520. static void display_scroll_message (int *scroll, int width, int height, char *buf)
  2521. {
  2522.     struct DisplayText dt[256];
  2523.     int curr_dt = 0;
  2524.     char uparrow[2] = "\x18";
  2525.     char downarrow[2] = "\x19";
  2526.     char textcopy[2048];
  2527.     char *copy;
  2528.     int leftoffs,topoffs;
  2529.     int first = *scroll;
  2530.     int buflines,showlines;
  2531.     int i;
  2532.  
  2533.  
  2534.     /* draw box */
  2535.     leftoffs = (Machine->uiwidth - Machine->uifontwidth * (width + 1)) / 2;
  2536.     if (leftoffs < 0) leftoffs = 0;
  2537.     topoffs = (Machine->uiheight - (3 * height + 1) * Machine->uifontheight / 2) / 2;
  2538.     drawbox(leftoffs,topoffs,(width + 1) * Machine->uifontwidth,(3 * height + 1) * Machine->uifontheight / 2);
  2539.  
  2540.     buflines = count_lines_in_buffer (buf);
  2541.     if (first > 0)
  2542.     {
  2543.         if (buflines <= height)
  2544.             first = 0;
  2545.         else
  2546.         {
  2547.             height--;
  2548.             if (first > (buflines - height))
  2549.                 first = buflines - height;
  2550.         }
  2551.         *scroll = first;
  2552.     }
  2553.  
  2554.     if (first != 0)
  2555.     {
  2556.         /* indicate that scrolling upward is possible */
  2557.         dt[curr_dt].text = uparrow;
  2558.         dt[curr_dt].color = DT_COLOR_WHITE;
  2559.         dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(uparrow)) / 2;
  2560.         dt[curr_dt].y = topoffs + (3*curr_dt+1)*Machine->uifontheight/2;
  2561.         curr_dt++;
  2562.     }
  2563.  
  2564.     if ((buflines - first) > height)
  2565.         showlines = height - 1;
  2566.     else
  2567.         showlines = height;
  2568.  
  2569.     /* skip to first line */
  2570.     while (first > 0)
  2571.     {
  2572.         char c;
  2573.  
  2574.         while ( (c = *buf++) )
  2575.         {
  2576.             if (c == '\n')
  2577.             {
  2578.                 first--;
  2579.                 break;
  2580.             }
  2581.         }
  2582.     }
  2583.  
  2584.     /* copy 'showlines' lines from buffer, starting with line 'first' */
  2585.     copy = textcopy;
  2586.     for (i = 0; i < showlines; i++)
  2587.     {
  2588.         char *copystart = copy;
  2589.  
  2590.         while (*buf && *buf != '\n')
  2591.         {
  2592.             *copy = *buf;
  2593.             copy++;
  2594.             buf++;
  2595.         }
  2596.         *copy = '\0';
  2597.         copy++;
  2598.         if (*buf == '\n')
  2599.             buf++;
  2600.  
  2601.         if (*copystart == '\t')    /* center text */
  2602.         {
  2603.             copystart++;
  2604.             dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * (copy - copystart)) / 2;
  2605.         }
  2606.         else
  2607.             dt[curr_dt].x = leftoffs + Machine->uifontwidth/2;
  2608.  
  2609.         dt[curr_dt].text = copystart;
  2610.         dt[curr_dt].color = DT_COLOR_WHITE;
  2611.         dt[curr_dt].y = topoffs + (3*curr_dt+1)*Machine->uifontheight/2;
  2612.         curr_dt++;
  2613.     }
  2614.  
  2615.     if (showlines == (height - 1))
  2616.     {
  2617.         /* indicate that scrolling downward is possible */
  2618.         dt[curr_dt].text = downarrow;
  2619.         dt[curr_dt].color = DT_COLOR_WHITE;
  2620.         dt[curr_dt].x = (Machine->uiwidth - Machine->uifontwidth * strlen(downarrow)) / 2;
  2621.         dt[curr_dt].y = topoffs + (3*curr_dt+1)*Machine->uifontheight/2;
  2622.         curr_dt++;
  2623.     }
  2624.  
  2625.     dt[curr_dt].text = 0;    /* terminate array */
  2626.  
  2627.     displaytext(dt,0,0);
  2628. }
  2629.  
  2630.  
  2631. /* Display text entry for current driver from history.dat and mameinfo.dat. */
  2632. static int displayhistory (int selected)
  2633. {
  2634.     char *msg = "\tHistory not available\n\n\t\x1a Return to Main Menu \x1b";
  2635.     static int scroll = 0;
  2636.     static int lines = 0;
  2637.     static char *buf = 0;
  2638.     int    maxcols,maxrows;
  2639.     int sel;
  2640.  
  2641.  
  2642.     sel = selected - 1;
  2643.  
  2644.  
  2645.     maxcols = (Machine->uiwidth / Machine->uifontwidth) - 1;
  2646.     maxrows = (2 * Machine->uiheight - Machine->uifontheight) / (3 * Machine->uifontheight);
  2647.     maxcols -= 2;
  2648.     maxrows -= 8;
  2649.  
  2650.     if (!buf)
  2651.     {
  2652.         /* allocate a buffer for the text */
  2653.         buf = malloc (8192);
  2654.         if (buf)
  2655.         {
  2656.             /* try to load entry */
  2657.             if (load_driver_history (Machine->gamedrv, buf, 8192) == 0)
  2658.             {
  2659.                 scroll = 0;
  2660.                 wordwrap_text_buffer (buf, maxcols);
  2661.                 strcat(buf,"\n\t\x1a Return to Main Menu \x1b\n");
  2662.             }
  2663.             else
  2664.             {
  2665.                 free (buf);
  2666.                 buf = 0;
  2667.             }
  2668.         }
  2669.     }
  2670.  
  2671.     {
  2672.         if (buf)
  2673.             display_scroll_message (&scroll, maxcols, maxrows, buf);
  2674.         else
  2675.             displaymessagewindow (msg);
  2676.  
  2677.         if ((scroll > 0) && osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,4))
  2678.         {
  2679.             if (scroll == 2) scroll = 0;    /* 1 would be the same as 0, but with arrow on top */
  2680.             else scroll--;
  2681.         }
  2682.  
  2683.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,4))
  2684.         {
  2685.             if (scroll == 0) scroll = 2;    /* 1 would be the same as 0, but with arrow on top */
  2686.             else scroll++;
  2687.         }
  2688.  
  2689.         if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  2690.             sel = -1;
  2691.  
  2692.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  2693.             sel = -1;
  2694.  
  2695.         if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  2696.             sel = -2;
  2697.     }
  2698.  
  2699.     if (sel == -1 || sel == -2)
  2700.     {
  2701.         /* tell updatescreen() to clean after us */
  2702.         need_to_clear_bitmap = 1;
  2703.  
  2704.         /* force buffer to be recreated */
  2705.         if (buf)
  2706.         {
  2707.             free (buf);
  2708.             buf = 0;
  2709.         }
  2710.     }
  2711.  
  2712.     return sel + 1;
  2713.  
  2714. }
  2715.  
  2716.  
  2717. int    memcard_menu(int selection)
  2718. {
  2719.     int sel;
  2720.     int menutotal = 0;
  2721.     const char *menuitem[10];
  2722.     char    buffer[300];
  2723.     char    *msg;
  2724.     void    *f;
  2725.  
  2726.     sel = selection - 1 ;
  2727.  
  2728.     sprintf(buffer, "Load Memory Card %03d", mcd_number);
  2729.     menuitem[menutotal++] = buffer;
  2730.     menuitem[menutotal++] = "Eject Memory Card";
  2731.     menuitem[menutotal++] = "Create Memory Card";
  2732.     menuitem[menutotal++] = "Call Memory Card Manager (RESET)";
  2733.     menuitem[menutotal++] = "Return to Main Menu";
  2734.     menuitem[menutotal] = 0;
  2735.  
  2736.     if (mcd_action!=0)
  2737.     {
  2738.         switch(mcd_action)
  2739.         {
  2740.         case    1:
  2741.             msg = "\nFailed To Load Memory Card!\n\n";
  2742.             break;
  2743.         case    2:
  2744.             msg = "\nLoad OK!\n\n";
  2745.             break;
  2746.         case    3:
  2747.             msg = "\nMemory Card Ejected!\n\n";
  2748.             break;
  2749.         case    4:
  2750.             msg = "\nMemory Card Created OK!\n\n";
  2751.             break;
  2752.         case    5:
  2753.             msg = "\nFailed To Create Memory Card!\n(It already exists ?)\n\n";
  2754.             break;
  2755.         default:
  2756.             msg = "\nDAMN!! Internal Error!\n\n";
  2757.         }
  2758.         displaymessagewindow(msg);
  2759.         if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  2760.             mcd_action = 0;
  2761.     }
  2762.     else
  2763.     {
  2764.         displaymenu(menuitem,0,0,sel,0);
  2765.  
  2766.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_RIGHT,8))
  2767.             mcd_number = (mcd_number + 1) % 1000;
  2768.  
  2769.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_LEFT,8))
  2770.             mcd_number = (mcd_number + 999) % 1000;
  2771.  
  2772.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  2773.             sel = (sel + 1) % menutotal;
  2774.  
  2775.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  2776.             sel = (sel + menutotal - 1) % menutotal;
  2777.  
  2778.         if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  2779.         {
  2780.             switch(sel)
  2781.             {
  2782.             case 0:
  2783.                 neogeo_memcard_eject();
  2784.                 if (neogeo_memcard_load(mcd_number))
  2785.                 {
  2786.                     memcard_status=1;
  2787.                     memcard_number=mcd_number;
  2788.                     mcd_action = 2;
  2789.                 }
  2790.                 else
  2791.                     mcd_action = 1;
  2792.                 break;
  2793.             case 1:
  2794.                 neogeo_memcard_eject();
  2795.                 mcd_action = 3;
  2796.                 break;
  2797.             case 2:
  2798.                 if (neogeo_memcard_create(mcd_number))
  2799.                     mcd_action = 4;
  2800.                 else
  2801.                     mcd_action = 5;
  2802.                 break;
  2803.             case 3:
  2804.                 memcard_manager=1;
  2805.                 sel=-2;
  2806.                 machine_reset();
  2807.                 break;
  2808.             case 4:
  2809.                 sel=-1;
  2810.                 break;
  2811.             }
  2812.         }
  2813.  
  2814.         if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) || osd_key_pressed_memory (OSD_KEY_CANCEL))
  2815.             sel = -1;
  2816.  
  2817.         if (osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  2818.             sel = -2;
  2819.  
  2820.         if (sel == -1 || sel == -2)
  2821.         {
  2822.             /* tell updatescreen() to clean after us */
  2823.             need_to_clear_bitmap = 1;
  2824.         }
  2825.     }
  2826.  
  2827.     return sel + 1;
  2828. }
  2829.  
  2830.  
  2831.  
  2832. enum { UI_SWITCH = 0,UI_DEFKEY,UI_DEFJOY,UI_KEY,UI_JOY,UI_ANALOG,UI_CALIBRATE,
  2833.         UI_STATS,UI_CREDITS,UI_GAMEINFO,UI_HISTORY,
  2834.         UI_CHEAT,UI_RESET,UI_MEMCARD,UI_EXIT };
  2835.  
  2836. #define MAX_SETUPMENU_ITEMS 20
  2837. static const char *menu_item[MAX_SETUPMENU_ITEMS];
  2838. static int menu_action[MAX_SETUPMENU_ITEMS];
  2839. static int menu_total;
  2840.  
  2841.  
  2842. static void setup_menu_init(void)
  2843. {
  2844.     menu_total = 0;
  2845.  
  2846.     menu_item[menu_total] = "Dip Switches"; menu_action[menu_total++] = UI_SWITCH;
  2847.     menu_item[menu_total] = "Keys (this game)"; menu_action[menu_total++] = UI_KEY;
  2848.     menu_item[menu_total] = "Joystick (this game)"; menu_action[menu_total++] = UI_JOY;
  2849.     menu_item[menu_total] = "Keys (defaults)"; menu_action[menu_total++] = UI_DEFKEY;
  2850.     menu_item[menu_total] = "Joystick (defaults)"; menu_action[menu_total++] = UI_DEFJOY;
  2851.  
  2852.     /* Determine if there are any analog controls */
  2853.     {
  2854.         struct InputPort *in;
  2855.         int num;
  2856.  
  2857.         in = Machine->input_ports;
  2858.  
  2859.         num = 0;
  2860.         while (in->type != IPT_END)
  2861.         {
  2862.             if (((in->type & 0xff) > IPT_ANALOG_START) && ((in->type & 0xff) < IPT_ANALOG_END)
  2863.                     && !(!options.cheat && (in->type & IPF_CHEAT)))
  2864.                 num++;
  2865.             in++;
  2866.         }
  2867.  
  2868.         if (num != 0)
  2869.         {
  2870.             menu_item[menu_total] = "Analog Controls"; menu_action[menu_total++] = UI_ANALOG;
  2871.         }
  2872.     }
  2873.  
  2874.     /* Joystick calibration possible? */
  2875.     if ((osd_joystick_needs_calibration()) != 0)
  2876.     {
  2877.         menu_item[menu_total] = "Calibrate Joysticks"; menu_action[menu_total++] = UI_CALIBRATE;
  2878.     }
  2879.  
  2880.     menu_item[menu_total] = "Bookkeeping Info"; menu_action[menu_total++] = UI_STATS;
  2881.     menu_item[menu_total] = "Credits"; menu_action[menu_total++] = UI_CREDITS;
  2882.     menu_item[menu_total] = "Game Information"; menu_action[menu_total++] = UI_GAMEINFO;
  2883.     menu_item[menu_total] = "Game History"; menu_action[menu_total++] = UI_HISTORY;
  2884.  
  2885.     if (options.cheat)
  2886.     {
  2887.         menu_item[menu_total] = "Cheat"; menu_action[menu_total++] = UI_CHEAT;
  2888.     }
  2889.  
  2890. #ifndef NEOFREE
  2891. #ifndef TINY_COMPILE
  2892.     if (Machine->gamedrv->clone_of == &neogeo_bios ||
  2893.             (Machine->gamedrv->clone_of &&
  2894.                 Machine->gamedrv->clone_of->clone_of == &neogeo_bios))
  2895.     {
  2896.         menu_item[menu_total] = "Memory Card"; menu_action[menu_total++] = UI_MEMCARD;
  2897.     }
  2898. #endif
  2899. #endif
  2900.  
  2901.     menu_item[menu_total] = "Reset Game"; menu_action[menu_total++] = UI_RESET;
  2902.     menu_item[menu_total] = "Return to Game"; menu_action[menu_total++] = UI_EXIT;
  2903.     menu_item[menu_total] = 0; /* terminate array */
  2904. }
  2905.  
  2906.  
  2907. static int setup_menu(int selected)
  2908. {
  2909.     int sel,res;
  2910.     static int menu_lastselected = 0;
  2911.  
  2912.  
  2913.     if (selected == -1)
  2914.         sel = menu_lastselected;
  2915.     else sel = selected - 1;
  2916.  
  2917.     if (sel > 0xff)
  2918.     {
  2919.         switch (menu_action[sel & 0xff])
  2920.         {
  2921.             case UI_SWITCH:
  2922.                 res = setdipswitches(sel >> 8);
  2923.                 if (res == -1)
  2924.                 {
  2925.                     menu_lastselected = sel;
  2926.                     sel = -1;
  2927.                 }
  2928.                 else
  2929.                     sel = (sel & 0xff) | (res << 8);
  2930.                 break;
  2931.  
  2932.             case UI_DEFKEY:
  2933.                 res = setdefkeysettings(sel >> 8);
  2934.                 if (res == -1)
  2935.                 {
  2936.                     menu_lastselected = sel;
  2937.                     sel = -1;
  2938.                 }
  2939.                 else
  2940.                     sel = (sel & 0xff) | (res << 8);
  2941.                 break;
  2942.  
  2943.             case UI_DEFJOY:
  2944.                 res = setdefjoysettings(sel >> 8);
  2945.                 if (res == -1)
  2946.                 {
  2947.                     menu_lastselected = sel;
  2948.                     sel = -1;
  2949.                 }
  2950.                 else
  2951.                     sel = (sel & 0xff) | (res << 8);
  2952.                 break;
  2953.  
  2954.             case UI_KEY:
  2955.                 res = setkeysettings(sel >> 8);
  2956.                 if (res == -1)
  2957.                 {
  2958.                     menu_lastselected = sel;
  2959.                     sel = -1;
  2960.                 }
  2961.                 else
  2962.                     sel = (sel & 0xff) | (res << 8);
  2963.                 break;
  2964.  
  2965.             case UI_JOY:
  2966.                 res = setjoysettings(sel >> 8);
  2967.                 if (res == -1)
  2968.                 {
  2969.                     menu_lastselected = sel;
  2970.                     sel = -1;
  2971.                 }
  2972.                 else
  2973.                     sel = (sel & 0xff) | (res << 8);
  2974.                 break;
  2975.  
  2976.             case UI_ANALOG:
  2977.                 res = settraksettings(sel >> 8);
  2978.                 if (res == -1)
  2979.                 {
  2980.                     menu_lastselected = sel;
  2981.                     sel = -1;
  2982.                 }
  2983.                 else
  2984.                     sel = (sel & 0xff) | (res << 8);
  2985.                 break;
  2986.  
  2987.             case UI_CALIBRATE:
  2988.                 res = calibratejoysticks(sel >> 8);
  2989.                 if (res == -1)
  2990.                 {
  2991.                     menu_lastselected = sel;
  2992.                     sel = -1;
  2993.                 }
  2994.                 else
  2995.                     sel = (sel & 0xff) | (res << 8);
  2996.                 break;
  2997.  
  2998.  
  2999.             case UI_STATS:
  3000.                 res = mame_stats(sel >> 8);
  3001.                 if (res == -1)
  3002.                 {
  3003.                     menu_lastselected = sel;
  3004.                     sel = -1;
  3005.                 }
  3006.                 else
  3007.                     sel = (sel & 0xff) | (res << 8);
  3008.                 break;
  3009.  
  3010.             case UI_CREDITS:
  3011.                 res = displaycredits(sel >> 8);
  3012.                 if (res == -1)
  3013.                 {
  3014.                     menu_lastselected = sel;
  3015.                     sel = -1;
  3016.                 }
  3017.                 else
  3018.                     sel = (sel & 0xff) | (res << 8);
  3019.                 break;
  3020.  
  3021.             case UI_GAMEINFO:
  3022.                 res = displaygameinfo(sel >> 8);
  3023.                 if (res == -1)
  3024.                 {
  3025.                     menu_lastselected = sel;
  3026.                     sel = -1;
  3027.                 }
  3028.                 else
  3029.                     sel = (sel & 0xff) | (res << 8);
  3030.                 break;
  3031.             case UI_HISTORY:
  3032.                 res = displayhistory(sel >> 8);
  3033.                 if (res == -1)
  3034.                 {
  3035.                     menu_lastselected = sel;
  3036.                     sel = -1;
  3037.                 }
  3038.                 else
  3039.                     sel = (sel & 0xff) | (res << 8);
  3040.                 break;
  3041.  
  3042.             case UI_CHEAT:
  3043. osd_sound_enable(0);
  3044. while (osd_key_pressed(OSD_KEY_UI_SELECT))
  3045.     osd_update_video_and_audio();     /* give time to the sound hardware to apply the volume change */
  3046.                 cheat_menu();
  3047. osd_sound_enable(1);
  3048. sel = sel & 0xff;
  3049.                 break;
  3050.  
  3051.             case UI_MEMCARD:
  3052.                 res = memcard_menu(sel >> 8);
  3053.                 if (res == -1)
  3054.                 {
  3055.                     menu_lastselected = sel;
  3056.                     sel = -1;
  3057.                 }
  3058.                 else
  3059.                     sel = (sel & 0xff) | (res << 8);
  3060.                 break;
  3061.         }
  3062.  
  3063.         return sel + 1;
  3064.     }
  3065.  
  3066.  
  3067.     displaymenu(menu_item,0,0,sel,0);
  3068.  
  3069.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  3070.         sel = (sel + 1) % menu_total;
  3071.  
  3072.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  3073.         sel = (sel + menu_total - 1) % menu_total;
  3074.  
  3075.     if (osd_key_pressed_memory(OSD_KEY_UI_SELECT))
  3076.     {
  3077.         switch (menu_action[sel])
  3078.         {
  3079.             case UI_SWITCH:
  3080.             case UI_DEFKEY:
  3081.             case UI_DEFJOY:
  3082.             case UI_KEY:
  3083.             case UI_JOY:
  3084.             case UI_ANALOG:
  3085.             case UI_CALIBRATE:
  3086.             case UI_STATS:
  3087.             case UI_CREDITS:
  3088.             case UI_GAMEINFO:
  3089.             case UI_HISTORY:
  3090.             case UI_CHEAT:
  3091.             case UI_MEMCARD:
  3092.                 sel |= 0x100;
  3093.                 /* tell updatescreen() to clean after us */
  3094.                 need_to_clear_bitmap = 1;
  3095.                 break;
  3096.  
  3097.             case UI_RESET:
  3098.                 machine_reset();
  3099.                 break;
  3100.  
  3101.             case UI_EXIT:
  3102.                 menu_lastselected = 0;
  3103.                 sel = -1;
  3104.                 break;
  3105.         }
  3106.     }
  3107.  
  3108.     if (osd_key_pressed_memory(OSD_KEY_FAST_EXIT) ||
  3109.             osd_key_pressed_memory(OSD_KEY_CANCEL) ||
  3110.             osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  3111.     {
  3112.         menu_lastselected = sel;
  3113.         sel = -1;
  3114.     }
  3115.  
  3116.     if (sel == -1)
  3117.     {
  3118.         /* tell updatescreen() to clean after us */
  3119.         need_to_clear_bitmap = 1;
  3120.     }
  3121.  
  3122.     return sel + 1;
  3123. }
  3124.  
  3125.  
  3126.  
  3127. /*********************************************************************
  3128.  
  3129.   start of On Screen Display handling
  3130.  
  3131. *********************************************************************/
  3132.  
  3133. static void displayosd(const char *text,int percentage)
  3134. {
  3135.     struct DisplayText dt[2];
  3136.     int avail;
  3137.  
  3138.  
  3139.     avail = (Machine->uiwidth / Machine->uifontwidth) * 19 / 20;
  3140.  
  3141.     drawbox((Machine->uiwidth - Machine->uifontwidth * avail) / 2,
  3142.             (Machine->uiheight - 7*Machine->uifontheight/2),
  3143.             avail * Machine->uifontwidth,
  3144.             3*Machine->uifontheight);
  3145.  
  3146.     avail--;
  3147.  
  3148.     drawbar((Machine->uiwidth - Machine->uifontwidth * avail) / 2,
  3149.             (Machine->uiheight - 3*Machine->uifontheight),
  3150.             avail * Machine->uifontwidth,
  3151.             Machine->uifontheight,
  3152.             percentage);
  3153.  
  3154.     dt[0].text = text;
  3155.     dt[0].color = DT_COLOR_WHITE;
  3156.     dt[0].x = (Machine->uiwidth - Machine->uifontwidth * strlen(text)) / 2;
  3157.     dt[0].y = (Machine->uiheight - 2*Machine->uifontheight) + 2;
  3158.     dt[1].text = 0;    /* terminate array */
  3159.     displaytext(dt,0,0);
  3160. }
  3161.  
  3162.  
  3163.  
  3164. static void onscrd_volume(int increment,int arg)
  3165. {
  3166.     char buf[20];
  3167.     int attenuation;
  3168.  
  3169.     if (increment)
  3170.     {
  3171.         attenuation = osd_get_mastervolume();
  3172.         attenuation += increment;
  3173.         if (attenuation > 0) attenuation = 0;
  3174.         if (attenuation < -32) attenuation = -32;
  3175.         osd_set_mastervolume(attenuation);
  3176.     }
  3177.     attenuation = osd_get_mastervolume();
  3178.  
  3179.     sprintf(buf,"Volume %3ddB",attenuation);
  3180.     displayosd(buf,100 * (attenuation + 32) / 32);
  3181. }
  3182.  
  3183. static void onscrd_streamvol(int increment,int arg)
  3184. {
  3185.     static void *driver = 0;
  3186.     char buf[40];
  3187.     int volume,ch;
  3188.     int doallstreams = 0;
  3189.     int proportional = 0;
  3190.  
  3191.  
  3192.     if (osd_key_pressed(OSD_KEY_LSHIFT) || osd_key_pressed(OSD_KEY_RSHIFT))
  3193.         doallstreams = 1;
  3194.     if (!osd_key_pressed(OSD_KEY_LCONTROL) && !osd_key_pressed(OSD_KEY_RCONTROL))
  3195.         increment *= 5;
  3196.     if (osd_key_pressed(OSD_KEY_ALT) || osd_key_pressed(OSD_KEY_ALTGR))
  3197.         proportional = 1;
  3198.  
  3199.     if (increment)
  3200.     {
  3201.         if (proportional)
  3202.         {
  3203.             static int old_vol[MAX_STREAM_CHANNELS];
  3204.             float ratio = 1.0;
  3205.             int overflow = 0;
  3206.  
  3207.             if (driver != Machine->drv)
  3208.             {
  3209.                 driver = (void *)Machine->drv;
  3210.                 for (ch = 0; ch < MAX_STREAM_CHANNELS; ch++)
  3211.                     old_vol[ch] = stream_get_volume(ch);
  3212.             }
  3213.  
  3214.             volume = stream_get_volume(arg);
  3215.             if (old_vol[arg])
  3216.                 ratio = (float)(volume + increment) / (float)old_vol[arg];
  3217.  
  3218.             for (ch = 0; ch < MAX_STREAM_CHANNELS; ch++)
  3219.             {
  3220.                 if (stream_get_name(ch) != 0)
  3221.                 {
  3222.                     volume = ratio * old_vol[ch];
  3223.                     if (volume < 0 || volume > 100)
  3224.                         overflow = 1;
  3225.                 }
  3226.             }
  3227.  
  3228.             if (!overflow)
  3229.             {
  3230.                 for (ch = 0; ch < MAX_STREAM_CHANNELS; ch++)
  3231.                 {
  3232.                     volume = ratio * old_vol[ch];
  3233.                     stream_set_volume(ch, volume);
  3234.                 }
  3235.             }
  3236.         }
  3237.         else
  3238.         {
  3239.             driver = 0; /* force reset of saved volumes */
  3240.  
  3241.             volume = stream_get_volume(arg);
  3242.             volume += increment;
  3243.             if (volume > 100) volume = 100;
  3244.             if (volume < 0) volume = 0;
  3245.  
  3246.             if (doallstreams)
  3247.             {
  3248.                 for (ch = 0;ch < MAX_STREAM_CHANNELS;ch++)
  3249.                     stream_set_volume(ch,volume);
  3250.             }
  3251.             else
  3252.                 stream_set_volume(arg,volume);
  3253.         }
  3254.     }
  3255.     volume = stream_get_volume(arg);
  3256.  
  3257.     if (proportional)
  3258.         sprintf(buf,"ALL CHANNELS Relative %3d%%", volume);
  3259.     else if (doallstreams)
  3260.         sprintf(buf,"ALL CHANNELS Volume %3d%%",volume);
  3261.     else
  3262.         sprintf(buf,"%s Volume %3d%%",stream_get_name(arg),volume);
  3263.     displayosd(buf,volume);
  3264. }
  3265.  
  3266. static void onscrd_brightness(int increment,int arg)
  3267. {
  3268.     char buf[20];
  3269.     int brightness;
  3270.  
  3271.  
  3272.     if (increment)
  3273.     {
  3274.         brightness = osd_get_brightness();
  3275.         brightness += 5 * increment;
  3276.         if (brightness < 0) brightness = 0;
  3277.         if (brightness > 100) brightness = 100;
  3278.         osd_set_brightness(brightness);
  3279.     }
  3280.     brightness = osd_get_brightness();
  3281.  
  3282.     sprintf(buf,"Brightness %3d%%",brightness);
  3283.     displayosd(buf,brightness);
  3284. }
  3285.  
  3286. static void onscrd_gamma(int increment,int arg)
  3287. {
  3288.     char buf[20];
  3289.     float gamma_correction;
  3290.  
  3291.     /* MLR 990316 different gamma handling for vector games */
  3292.     if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
  3293.     {
  3294.         if (increment)
  3295.         {
  3296.             gamma_correction = vector_get_gamma();
  3297.  
  3298.             gamma_correction += 0.05 * increment;
  3299.             if (gamma_correction < 0.5) gamma_correction = 0.5;
  3300.             if (gamma_correction > 2.0) gamma_correction = 2.0;
  3301.  
  3302.             vector_set_gamma(gamma_correction);
  3303.         }
  3304.         gamma_correction = vector_get_gamma();
  3305.     }
  3306.     else
  3307.     {
  3308.         if (increment)
  3309.         {
  3310.             gamma_correction = osd_get_gamma();
  3311.  
  3312.             gamma_correction += 0.05 * increment;
  3313.             if (gamma_correction < 0.5) gamma_correction = 0.5;
  3314.             if (gamma_correction > 2.0) gamma_correction = 2.0;
  3315.  
  3316.             osd_set_gamma(gamma_correction);
  3317.         }
  3318.         gamma_correction = osd_get_gamma();
  3319.     }
  3320.  
  3321.     sprintf(buf,"Gamma %1.2f",gamma_correction);
  3322.     displayosd(buf,100*(gamma_correction-0.5)/(2.0-0.5));
  3323. }
  3324.  
  3325.  
  3326. #define MAX_OSD_ITEMS 30
  3327. static void (*onscrd_fnc[MAX_OSD_ITEMS])(int increment,int arg);
  3328. static int onscrd_arg[MAX_OSD_ITEMS];
  3329. static int onscrd_total_items;
  3330.  
  3331. static void onscrd_init(void)
  3332. {
  3333.     int item,ch;
  3334.  
  3335.  
  3336.     item = 0;
  3337.  
  3338.     onscrd_fnc[item] = onscrd_volume;
  3339.     onscrd_arg[item] = 0;
  3340.     item++;
  3341.  
  3342.     for (ch = 0;ch < MAX_STREAM_CHANNELS;ch++)
  3343.     {
  3344.         if (stream_get_name(ch) != 0)
  3345.         {
  3346.             onscrd_fnc[item] = onscrd_streamvol;
  3347.             onscrd_arg[item] = ch;
  3348.             item++;
  3349.         }
  3350.     }
  3351.  
  3352.     onscrd_fnc[item] = onscrd_brightness;
  3353.     onscrd_arg[item] = 0;
  3354.     item++;
  3355.  
  3356.     onscrd_fnc[item] = onscrd_gamma;
  3357.     onscrd_arg[item] = 0;
  3358.     item++;
  3359.  
  3360.     onscrd_total_items = item;
  3361. }
  3362.  
  3363. static int on_screen_display(int selected)
  3364. {
  3365.     int increment,sel;
  3366.     static int lastselected = 0;
  3367.  
  3368.  
  3369.     if (selected == -1)
  3370.         sel = lastselected;
  3371.     else sel = selected - 1;
  3372.  
  3373.     increment = 0;
  3374.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_LEFT,8))
  3375.         increment = -1;
  3376.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_RIGHT,8))
  3377.         increment = 1;
  3378.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  3379.         sel = (sel + 1) % onscrd_total_items;
  3380.     if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  3381.         sel = (sel + onscrd_total_items - 1) % onscrd_total_items;
  3382.  
  3383.     (*onscrd_fnc[sel])(increment,onscrd_arg[sel]);
  3384.  
  3385.     lastselected = sel;
  3386.  
  3387.     if (osd_key_pressed_memory(OSD_KEY_ON_SCREEN_DISPLAY))
  3388.     {
  3389.         sel = -1;
  3390.  
  3391.         /* tell updatescreen() to clean after us */
  3392.         need_to_clear_bitmap = 1;
  3393.     }
  3394.  
  3395.     return sel + 1;
  3396. }
  3397.  
  3398. /*********************************************************************
  3399.  
  3400.   end of On Screen Display handling
  3401.  
  3402. *********************************************************************/
  3403.  
  3404.  
  3405. static void displaymessage(const char *text)
  3406. {
  3407.     struct DisplayText dt[2];
  3408.     int avail;
  3409.  
  3410.  
  3411.     avail = strlen(text)+2;
  3412.  
  3413.     drawbox((Machine->uiwidth - Machine->uifontwidth * avail) / 2,
  3414.             Machine->uiheight - 3*Machine->uifontheight,
  3415.             avail * Machine->uifontwidth,
  3416.             2*Machine->uifontheight);
  3417.  
  3418.     dt[0].text = text;
  3419.     dt[0].color = DT_COLOR_WHITE;
  3420.     dt[0].x = (Machine->uiwidth - Machine->uifontwidth * strlen(text)) / 2;
  3421.     dt[0].y = Machine->uiheight - 5*Machine->uifontheight/2;
  3422.     dt[1].text = 0;    /* terminate array */
  3423.     displaytext(dt,0,0);
  3424. }
  3425.  
  3426.  
  3427. static char messagetext[80];
  3428. static int messagecounter;
  3429.  
  3430. void usrintf_showmessage(const char *text)
  3431. {
  3432.     strcpy(messagetext,text);
  3433.     messagecounter = 2 * Machine->drv->frames_per_second;
  3434. }
  3435.  
  3436.  
  3437.  
  3438.  
  3439. static int setup_selected;
  3440. static int osd_selected;
  3441. static int jukebox_selected;
  3442.  
  3443. int handle_user_interface(void)
  3444. {
  3445.     static int show_total_colors;
  3446.  
  3447.  
  3448.     /* if the user pressed F12, save the screen to a file */
  3449.     if (osd_key_pressed_memory(OSD_KEY_SNAPSHOT))
  3450.         osd_save_snapshot();
  3451.  
  3452.     /* This call is for the cheat, it must be called at least each frames */
  3453.     if (options.cheat) DoCheat();
  3454.  
  3455.     if (osd_key_pressed_memory (OSD_KEY_FAST_EXIT)) return 1;
  3456.  
  3457.     /* if the user pressed ESC, stop the emulation */
  3458.     /* but don't quit if the setup menu is on screen */
  3459.     if (setup_selected == 0 && osd_key_pressed_memory(OSD_KEY_CANCEL))
  3460.         return 1;
  3461.  
  3462.     if (setup_selected == 0 && osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  3463.     {
  3464.         setup_selected = -1;
  3465.         if (osd_selected != 0)
  3466.         {
  3467.             osd_selected = 0;    /* disable on screen display */
  3468.             /* tell updatescreen() to clean after us */
  3469.             need_to_clear_bitmap = 1;
  3470.         }
  3471.     }
  3472.     if (setup_selected != 0) setup_selected = setup_menu(setup_selected);
  3473.  
  3474.     if (osd_selected == 0 && osd_key_pressed_memory(OSD_KEY_ON_SCREEN_DISPLAY))
  3475.     {
  3476.         osd_selected = -1;
  3477.         if (setup_selected != 0)
  3478.         {
  3479.             setup_selected = 0;    /* disable setup menu */
  3480.             /* tell updatescreen() to clean after us */
  3481.             need_to_clear_bitmap = 1;
  3482.         }
  3483.     }
  3484.     if (osd_selected != 0) osd_selected = on_screen_display(osd_selected);
  3485.  
  3486.  
  3487. #if 0
  3488.     if (osd_key_pressed_memory(OSD_KEY_BACKSPACE))
  3489.     {
  3490.         if (jukebox_selected != -1)
  3491.         {
  3492.             jukebox_selected = -1;
  3493.             cpu_halt(0,1);
  3494.         }
  3495.         else
  3496.         {
  3497.             jukebox_selected = 0;
  3498.             cpu_halt(0,0);
  3499.         }
  3500.     }
  3501.  
  3502.     if (jukebox_selected != -1)
  3503.     {
  3504.         char buf[40];
  3505.         watchdog_reset_w(0,0);
  3506.         if (osd_key_pressed_memory(OSD_KEY_LCONTROL))
  3507.         {
  3508. #include "cpu/z80/z80.h"
  3509.             soundlatch_w(0,jukebox_selected);
  3510.             cpu_cause_interrupt(1,Z80_NMI_INT);
  3511.         }
  3512.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_RIGHT,8))
  3513.         {
  3514.             jukebox_selected = (jukebox_selected + 1) & 0xff;
  3515.         }
  3516.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_LEFT,8))
  3517.         {
  3518.             jukebox_selected = (jukebox_selected - 1) & 0xff;
  3519.         }
  3520.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_UP,8))
  3521.         {
  3522.             jukebox_selected = (jukebox_selected + 16) & 0xff;
  3523.         }
  3524.         if (osd_key_pressed_memory_repeat(OSD_KEY_UI_DOWN,8))
  3525.         {
  3526.             jukebox_selected = (jukebox_selected - 16) & 0xff;
  3527.         }
  3528.         sprintf(buf,"sound cmd %02x",jukebox_selected);
  3529.         displaymessage(buf);
  3530.     }
  3531. #endif
  3532.  
  3533.  
  3534.     /* if the user pressed F3, reset the emulation */
  3535.     if (osd_key_pressed_memory(OSD_KEY_RESET_MACHINE))
  3536.         machine_reset();
  3537.  
  3538.  
  3539.     if (osd_key_pressed_memory(OSD_KEY_PAUSE)) /* pause the game */
  3540.     {
  3541.         float orig_brt;
  3542.         int pressed;
  3543.  
  3544.  
  3545. /*        osd_selected = 0;       disable on screen display, since we are going   */
  3546.                             /* to change parameters affected by it */
  3547.  
  3548.         osd_sound_enable(0);
  3549.         orig_brt = osd_get_brightness();
  3550.         osd_set_brightness(orig_brt * 0.65);
  3551.  
  3552.         pressed = 1;
  3553.  
  3554.         while (pressed || osd_key_pressed_memory(OSD_KEY_UNPAUSE) == 0)
  3555.         {
  3556. #ifdef MAME_NET
  3557.             osd_net_sync();
  3558. #endif /* MAME_NET */
  3559.             osd_profiler(OSD_PROFILE_VIDEO);
  3560.             if (need_to_clear_bitmap || bitmap_dirty)
  3561.             {
  3562.                 osd_clearbitmap(Machine->scrbitmap);
  3563.                 need_to_clear_bitmap = 0;
  3564.                 (*Machine->drv->vh_update)(Machine->scrbitmap,bitmap_dirty);
  3565.                 bitmap_dirty = 0;
  3566.             }
  3567. #ifdef MAME_DEBUG
  3568. /* keep calling vh_screenrefresh() while paused so we can stuff */
  3569. /* debug code in there */
  3570. (*Machine->drv->vh_update)(Machine->scrbitmap,bitmap_dirty);
  3571. bitmap_dirty = 0;
  3572. #endif
  3573.             osd_profiler(OSD_PROFILE_END);
  3574.  
  3575.             if (osd_key_pressed_memory (OSD_KEY_FAST_EXIT)) return 1;
  3576.  
  3577.             if (setup_selected == 0 && osd_key_pressed_memory(OSD_KEY_CANCEL))
  3578.                 return 1;
  3579.  
  3580.             if (setup_selected == 0 && osd_key_pressed_memory(OSD_KEY_CONFIGURE))
  3581.             {
  3582.                 setup_selected = -1;
  3583.                 if (osd_selected != 0)
  3584.                 {
  3585.                     osd_selected = 0;    /* disable on screen display */
  3586.                     /* tell updatescreen() to clean after us */
  3587.                     need_to_clear_bitmap = 1;
  3588.                 }
  3589.             }
  3590.             if (setup_selected != 0) setup_selected = setup_menu(setup_selected);
  3591.  
  3592.             if (osd_selected == 0 && osd_key_pressed_memory(OSD_KEY_ON_SCREEN_DISPLAY))
  3593.             {
  3594.                 osd_selected = -1;
  3595.                 if (setup_selected != 0)
  3596.                 {
  3597.                     setup_selected = 0;    /* disable setup menu */
  3598.                     /* tell updatescreen() to clean after us */
  3599.                     need_to_clear_bitmap = 1;
  3600.                 }
  3601.             }
  3602.             if (osd_selected != 0) osd_selected = on_screen_display(osd_selected);
  3603.  
  3604.             /* show popup message if any */
  3605.             if (messagecounter > 0) displaymessage(messagetext);
  3606.  
  3607.             osd_update_video_and_audio();
  3608.  
  3609.             if (!osd_key_pressed(OSD_KEY_PAUSE)) pressed = 0;
  3610.         }
  3611.  
  3612.         osd_sound_enable(1);
  3613.         osd_set_brightness(orig_brt);
  3614.     }
  3615.  
  3616.  
  3617.     /* show popup message if any */
  3618.     if (messagecounter > 0)
  3619.     {
  3620.         displaymessage(messagetext);
  3621.  
  3622.         if (--messagecounter == 0)
  3623.             /* tell updatescreen() to clean after us */
  3624.             need_to_clear_bitmap = 1;
  3625.     }
  3626.  
  3627.  
  3628. #ifdef MAME_DEBUG
  3629.     if (osd_key_pressed_memory(OSD_KEY_SHOW_TOTAL_COLORS))
  3630.     {
  3631.         show_total_colors ^= 1;
  3632.         if (show_total_colors == 0)
  3633.             /* tell updatescreen() to clean after us */
  3634.             need_to_clear_bitmap = 1;
  3635.     }
  3636.  
  3637.     if (show_total_colors)
  3638.     {
  3639.         showtotalcolors();
  3640.     }
  3641. #endif
  3642.  
  3643.  
  3644.     /* if the user pressed F4, show the character set */
  3645.     if (osd_key_pressed_memory(OSD_KEY_SHOW_GFX))
  3646.     {
  3647.         osd_sound_enable(0);
  3648.  
  3649.         showcharset();
  3650.  
  3651.         osd_sound_enable(1);
  3652.     }
  3653.  
  3654.     return 0;
  3655. }
  3656.  
  3657.  
  3658. void init_user_interface(void)
  3659. {
  3660.     setup_menu_init();
  3661.     setup_selected = 0;
  3662.  
  3663.     onscrd_init();
  3664.     osd_selected = 0;
  3665.  
  3666.     jukebox_selected = -1;
  3667. }
  3668.  
  3669. int onscrd_active(void)
  3670. {
  3671.     return osd_selected;
  3672. }
  3673.  
  3674. int setup_active(void)
  3675. {
  3676.     return setup_selected;
  3677. }
  3678.